blob: 4bde36ec2f562b8f57eb62d25447175a1b625195 [file] [log] [blame]
#ifndef UIMA_LOWLEVEL_INTERNAL_INDEXES_HPP
#define UIMA_LOWLEVEL_INTERNAL_INDEXES_HPP
/** \file lowlevel_internal_indexes.hpp .
-----------------------------------------------------------------------------
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-----------------------------------------------------------------------------
Description:
-----------------------------------------------------------------------------
-------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp" // must be first file to be included to get pragmas
#include <algorithm>
#include <memory>
#include <set>
#include "uima/lowlevel_index.hpp"
#include "uima/lowlevel_indexcomparator.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/types.h"
#include "uima/macros.h"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
namespace uima {
namespace lowlevel {
class IndexIterator;
class SingleOrderedIndexIterator;
class IndexRepository;
class KeyFeatureLexicographicLess;
class SingleSetIndex;
}
}
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
/**
* This file containts all different index types, i.e., any implementation
* of single and composite indexes for the falvors "ordered", "set", and "FIFO".
*/
namespace uima {
namespace lowlevel {
namespace internal {
/**
* The base class for all single indexes.
*/
class UIMA_LINK_IMPORTSPEC SingleIndex : public IndexABase {
protected:
SingleIndex(IndexRepository const & aIndexRepository,
TyFSType tyType);
public:
/**
* check if a feature structure is contained in the index.
* This is different from find() since it always tests for
* identity rather equivalence.
*/
virtual bool contains(TyFS) const;
virtual IndexIterator* createTypeSetIterator(std::set<uima::lowlevel::TyFSType> const & crType) const {
assert( crType.size() <= 1 );
if (crType.size() == 1) {
assert( *(crType.begin()) == getType() );
}
return createIterator();
}
};
/**
* A single index with a comparator.
*/
class UIMA_LINK_IMPORTSPEC ComparatorSingleIndex : public SingleIndex {
protected:
IndexComparator const * iv_cpComparator;
ComparatorSingleIndex(IndexRepository const & crIndexRepository,
uima::lowlevel::TyFSType tyType,
IndexComparator const * cpComparator);
public:
virtual TyFS find(TyFS) const;
IndexComparator const * getComparator() const {
return iv_cpComparator;
}
};
/**
* A single ordered index. Inserting works fast if the elements
* are inserted already in the correct order. Slow otherwise...
*/
class UIMA_LINK_IMPORTSPEC OrderedSingleIndex : public ComparatorSingleIndex {
public:
typedef std::vector<TyFS> TyStructures;
private:
TyStructures iv_tyStructures;
protected:
void add(TyFS fs);
void remove(TyFS fs);
void reset();
public:
OrderedSingleIndex(IndexRepository const & aIndexRepository,
TyFSType aType,
IndexComparator const * );
size_t getSize() const {
return iv_tyStructures.size();
}
IndexIterator* createIterator() const;
TyFS find(TyFS fs) const;
std::vector<TyFS> const * getVector() const {
return & iv_tyStructures;
}
#ifndef NDEBUG
bool debugIsConsistent() const;
#endif
};
/**
* This class is a simply adapter to make a binary function out of a
* comparator.
* @see SetSingleIndex
*/
class UIMA_LINK_IMPORTSPEC IndexComparatorLess : public std::binary_function<TyFS, TyFS, bool> {
private:
IndexComparator const * iv_cpclComparator;
FSHeap const * iv_heap;
IndexComparatorLess()
: iv_cpclComparator(NULL),
iv_heap(NULL) {
assertWithMsg(false, "Default constructor for STL compliance only!");
};
public:
IndexComparatorLess(IndexComparator const * aComparator,
FSHeap const & heap)
: iv_cpclComparator(aComparator),
iv_heap(&heap) {
assert( EXISTS(iv_cpclComparator) );
}
bool operator()(TyFS fs1, TyFS fs2) const {
assert( EXISTS(iv_cpclComparator) );
assert( EXISTS(iv_heap) );
UIMA_TPRINT("Comparing fs " << (long) fs1 << " with " << (long) fs2 << ". result: " << iv_cpclComparator->compare(*iv_heap, fs1, fs2) );
return iv_cpclComparator->compare(*iv_heap, fs1, fs2) > 0;
}
};
/**
* A single set index.
*/
class UIMA_LINK_IMPORTSPEC SetSingleIndex : public ComparatorSingleIndex {
public:
typedef std::set<TyFS, IndexComparatorLess> TyStructures;
private:
// the set is allocated on the heap due to template problems with the Solaris compiler
TyStructures * iv_pStructures;
protected:
void add(TyFS fs) {
assert( EXISTS(iv_pStructures) );
(void) iv_pStructures->insert(fs);
}
void remove(TyFS fs) {
assert( EXISTS(iv_pStructures) );
(void) iv_pStructures->erase(fs);
}
void reset();
public:
SetSingleIndex(IndexRepository const & aIndexRepository,
TyFSType aType,
IndexComparator const * aComparator);
~SetSingleIndex();
size_t getSize() const {
assert( EXISTS(iv_pStructures) );
return iv_pStructures->size();
}
IndexIterator* createIterator() const;
TyFS find(TyFS fs) const {
assert( EXISTS(iv_pStructures) );
TyStructures::const_iterator it = iv_pStructures->find(fs);
if (it == iv_pStructures->end()) {
return 0;
}
return *it;
}
};
/**
* A single index behaving like a FIFO (a vector).
* A comparator is not needed here.
*/
class UIMA_LINK_IMPORTSPEC FIFOSingleIndex : public SingleIndex {
public:
typedef std::vector<TyFS> TyStructures;
private:
TyStructures iv_tyFIFO;
protected:
void add(TyFS fs) {
iv_tyFIFO.push_back(fs);
}
void reset() {
iv_tyFIFO.clear();
}
void remove(TyFS tyFS) {
TyStructures::iterator it = std::find(iv_tyFIFO.begin(), iv_tyFIFO.end(), tyFS);
if (it == iv_tyFIFO.end() ) {
return;
}
iv_tyFIFO.erase(it);
}
public:
FIFOSingleIndex(IndexRepository const & aIndexRepository,
TyFSType aType)
: SingleIndex(aIndexRepository, aType) {}
size_t getSize() const {
return iv_tyFIFO.size();
}
TyFS find(TyFS fs) const {
TyStructures::const_iterator it = std::find(iv_tyFIFO.begin(), iv_tyFIFO.end(), fs);
if (it == iv_tyFIFO.end()) {
return 0;
}
return *it;
}
IndexIterator* createIterator() const;
std::vector<TyFS> const * getVector() const {
return & iv_tyFIFO;
}
};
////////////////////////////////////////////////////////////////////////
// Composite indexes
/**
* The base class for all composite indexes. All methods are implemented
* but may be overwritten by subclasses.
*/
class UIMA_LINK_IMPORTSPEC CompositeIndex : public IndexABase {
public:
typedef std::vector<SingleIndex*> TyComponents;
protected:
TyComponents iv_tyComponents;
void add(TyFS /*fs*/) {
assertWithMsg(false, "Add operation not supported on CompositeIndex!");
}
void remove(TyFS /*fs*/) {
assertWithMsg(false, "Remove operation not supported on CompositeIndex!");
}
void reset() {
assertWithMsg(false, "Reset operation not supported on CompositeIndex!");
}
CompositeIndex(IndexRepository const & aIndexRepository,
uima::lowlevel::TyFSType tyType);
/**
* get all the components for the respective types.
*/
void getComponentsForTypes(std::set<uima::lowlevel::TyFSType> const & crTypes, TyComponents & crResult) const;
public:
void addComponent(SingleIndex* pclIndex) {
assert( iv_crTypeSystem.subsumes( getType(), pclIndex->getType() ) );
iv_tyComponents.push_back(pclIndex);
}
virtual size_t getSize() const;
virtual TyFS find(TyFS fs) const;
};
/**
* generic implementation of a composite index with a cache of all feature structures.
* This cache maybe used for fast iterating over all feature structures.
* The cache type T can either be an STL vector or set.
*/
template <class T>
class CachedCompositeIndex : public CompositeIndex {
protected:
T iv_cache;
uima::lowlevel::IndexComparator const * iv_comparator;
CachedCompositeIndex(IndexRepository const & aIndexRepository,
uima::lowlevel::TyFSType tyType,
IndexComparator const *);
// generic implementation of clearAndFillCache, maybe overwritten by subclasses
// this method is here because if it is in the cpp file, we get linking problems on Solaris.
virtual void clearAndFillCache() {
iv_cache.clear();
TyComponents::const_iterator cit;
for (cit = iv_tyComponents.begin(); cit != iv_tyComponents.end(); ++cit) {
SingleIndex const * index = (*cit);
std::unique_ptr<IndexIterator> apit( index->createIterator() );
for (apit->moveToFirst(); apit->isValid(); apit->moveToNext()) {
iv_cache.insert(iv_cache.end(), apit->get() );
}
}
}
public:
IndexIterator* createIterator() const;
IndexIterator* createTypeSetIterator(std::set<uima::lowlevel::TyFSType> const & crTypes) const;
IndexComparator const * getComparator() const {
return iv_comparator;
}
};
/**
* A composite ordered index. The iterator is different than the one
* of the superclass in that a different comparison scheme is used.
*/
class OrderedCompositeIndex : public CachedCompositeIndex<std::vector<TyFS> > {
protected:
void clearAndFillCache();
public:
OrderedCompositeIndex(IndexRepository const & aIndexRepository,
uima::lowlevel::TyFSType tyType,
IndexComparator const * aComparator);
virtual ~OrderedCompositeIndex();
};
/**
* A composite set index.
*/
class SetCompositeIndex : public CachedCompositeIndex<std::set<TyFS> > {
protected:
public:
SetCompositeIndex(IndexRepository const & aIndexRepository,
uima::lowlevel::TyFSType tyType,
IndexComparator const * aComparator);
};
class FIFOCompositeIndex : public CachedCompositeIndex<std::vector<TyFS> > {
protected:
public:
FIFOCompositeIndex(IndexRepository const & crIndexRepository,
uima::lowlevel::TyFSType tyType);
};
} //namespace internal
} //namespace lowlevel
} //namespace uima
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
namespace uima {
namespace lowlevel {
namespace internal {
template<class T>
CachedCompositeIndex<T>::CachedCompositeIndex(IndexRepository const & aIndexRepository,
uima::lowlevel::TyFSType tyType,
IndexComparator const * comparator)
: CompositeIndex( aIndexRepository, tyType),
iv_comparator(comparator) {
}
} //namespace internal
} //namespace lowlevel
} //namespace uima
/* ----------------------------------------------------------------------- */
#endif