blob: c9d25e4fd4ffc2d2e2774852c4da69d895ec5af8 [file] [log] [blame]
/** \file lowlevel_indexrepository.cpp .
-----------------------------------------------------------------------------
* 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:
-----------------------------------------------------------------------------
-------------------------------------------------------------------------- */
//#define DEBUG_VERBOSE
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include "uima/macros.h"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/lowlevel_index.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/lowlevel_internal_indexfactory.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/engine.hpp"
#include "uima/msg.h"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
using namespace std;
namespace uima {
namespace lowlevel {
IndexRepository::IndexRepository(IndexDefinition const & indexDef,
uima::lowlevel::FSHeap & rFSHeap,
CAS & cas)
: iv_indexDefinition(indexDef),
iv_cas(cas),
iv_rFSHeap(rFSHeap),
iv_bIsInitialized(false) {
init();
}
void IndexRepository::init() {
UIMA_TPRINT("constructing index store");
iv_bIsInitialized = false;
assert( !iv_bIsInitialized );
iv_idMaximalTypeMapping.clear();
iv_idNonMaximalTypeIndexes.clear();
iv_indexes.clear();
iv_cacheDirtyFlags.clear();
iv_isUsed.clear();
iv_usedIndexes.clear();
size_t typeNum = iv_rFSHeap.getTypeSystem().getNumberOfTypes();
iv_idMaximalTypeMapping.resize( typeNum + 1 );
iv_indexes.resize( typeNum + 1);
iv_idNonMaximalTypeIndexes.resize( typeNum + 1 );
iv_cacheDirtyFlags.resize(typeNum+1);
iv_isUsed.assign(typeNum+1, false);
iv_bIsInitialized = true;
UIMA_TPRINT("index store constructed");
assert( iv_bIsInitialized );
vector<IndexDefinition::TyIndexID> ids;
iv_indexDefinition.getAllIndexIDs(ids);
size_t i;
for (i=0; i<ids.size(); ++i) {
IndexDefinition::TyIndexID const & id = ids[i];
uima::lowlevel::TyFSType indexType = iv_indexDefinition.getTypeForIndex(id);
uima::lowlevel::internal::IndexFactory const * factory = iv_indexDefinition.getFactory(id);
assert( EXISTS(factory) );
vector<TyFSType> subsumedTypes;
iv_indexDefinition.getTypeSystem().getSubsumedTypes(indexType, subsumedTypes);
size_t i;
// create the single indexes
for (i=0; i<subsumedTypes.size(); ++i) {
TyFSType type = subsumedTypes[i];
internal::SingleIndex* ix = factory->createSingleIndex(*this, type);
assert( type < iv_indexes.size() );
iv_idMaximalTypeMapping[type][id] = iv_indexes[type].size();
iv_indexes[type].push_back(ix);
}
// create all composite indexes
for (i=0; i<subsumedTypes.size(); ++i) {
TyFSType type = subsumedTypes[i];
if (!iv_indexDefinition.getTypeSystem().isMaximalType(type)) {
UIMA_TPRINT("creating index for non maximal type");
internal::CompositeIndex* compIx = factory->createCompositeIndex(*this, type);
iv_idNonMaximalTypeIndexes[type][id] = compIx;
// add single indexes
vector<TyFSType> subsumedTypes2;
iv_indexDefinition.getTypeSystem().getSubsumedTypes(type, subsumedTypes2);
size_t j;
for (j=0; j<subsumedTypes2.size(); ++j) {
TyFSType subsType = subsumedTypes2[j];
assert( iv_idMaximalTypeMapping[subsType].find(id) != iv_idMaximalTypeMapping[subsType].end() );
size_t pos = iv_idMaximalTypeMapping[subsType][id];
compIx->addComponent( iv_indexes[subsType][pos] );
UIMA_TPRINT("Adding single index of type " << iv_indexDefinition.getTypeSystem().getTypeName(subsType) );
}
}
}
}
}
IndexRepository::~IndexRepository() {
clearAll();
}
void IndexRepository::clearAll() {
size_t i,j;
// delete indexes
for (i=0; i<iv_indexes.size(); ++i) {
for (j=0; j<iv_indexes[i].size(); ++j) {
delete iv_indexes[i][j];
}
}
// delete idNonMaximalTypeIndexes
for (i=0; i<iv_idNonMaximalTypeIndexes.size(); ++i) {
map<IndexDefinition::TyIndexID, internal::CompositeIndex*>::iterator it;
for (it = iv_idNonMaximalTypeIndexes[i].begin(); it != iv_idNonMaximalTypeIndexes[i].end(); ++it) {
delete (*it).second;
}
}
iv_idMaximalTypeMapping.clear();
iv_idNonMaximalTypeIndexes.clear();
iv_indexes.clear();
iv_cacheDirtyFlags.clear();
}
void IndexRepository::getUsedIndexes(vector<TyFSType>& fillit) {
fillit.clear();
fillit.assign(iv_usedIndexes.begin(), iv_usedIndexes.end());
}
void IndexRepository::getIndexedFSs(vector<TyFS>& fillit) {
fillit.clear();
for (size_t i=0;i < iv_undefinedindex.size(); i++ ) {
TyFS tyFSHeapIndex = this->iv_undefinedindex[i];
fillit.push_back(tyFSHeapIndex);
}
for (size_t i=0; i<iv_usedIndexes.size(); ++i) {
vector<uima::lowlevel::internal::SingleIndex*> const & crSingleIndexes =
getAllSingleIndexesForType(iv_usedIndexes[i]);
for (size_t j=0; j<crSingleIndexes.size(); ++j) {
auto_ptr<uima::lowlevel::IndexIterator> apIt(crSingleIndexes[j]->createIterator());
for (apIt->moveToFirst(); apIt->isValid(); apIt->moveToNext()) {
uima::lowlevel::TyHeapCell pHeapCell = (uima::lowlevel::TyHeapCell) apIt->get();
TyFS tyFSHeapIndex = pHeapCell;
fillit.push_back( tyFSHeapIndex );
}
}
}
// eliminate duplicates
sort(fillit.begin(), fillit.end());
vector<TyFS>::iterator end = unique(fillit.begin(), fillit.end());
}
void IndexRepository::reset() {
// clear undefined index
iv_undefinedindex.clear();
// check if anything to do
if ( 0 == iv_usedIndexes.size())
return;
// Reset the indexes used
for (size_t i=0; i<iv_usedIndexes.size(); ++i) {
vector<uima::lowlevel::internal::SingleIndex*> const & crSingleIndexes = getAllSingleIndexesForType(iv_usedIndexes[i]);
for (size_t j=0; j<crSingleIndexes.size(); ++j) {
crSingleIndexes[j]->reset();
}
iv_cacheDirtyFlags[iv_usedIndexes[i]].clear();
iv_isUsed[iv_usedIndexes[i]] = false;
}
iv_usedIndexes.clear();
}
void IndexRepository::resetDefinitions() {
// reset all index data
clearAll();
init();
}
IndexABase const & IndexRepository::getLowlevelIndex(IndexDefinition::TyIndexID const & crID, TyFSType type) const {
assert( iv_bIsInitialized );
assert( iv_indexDefinition.getTypeSystem().isValidType(type) );
assert( iv_indexDefinition.isValidIndexId(crID) );
assert( iv_indexDefinition.getTypeSystem().subsumes( iv_indexDefinition.getTypeForIndex(crID), type) );
IndexABase* result = NULL;
if (iv_indexDefinition.getTypeSystem().isMaximalType(type)) {
UIMA_TPRINT("requested index for maximal type");
map<IndexDefinition::TyIndexID, size_t>::const_iterator cit = iv_idMaximalTypeMapping[type].find(crID);
assert( cit != iv_idMaximalTypeMapping[type].end() );
size_t i = (*cit).second;
assert( (i >=0) && (i<iv_indexes[type].size()));
result = iv_indexes[type][ i ];
} else {
UIMA_TPRINT("requested index for non maximal type");
map<IndexDefinition::TyIndexID, internal::CompositeIndex*>::const_iterator cit = iv_idNonMaximalTypeIndexes[type].find(crID);
assert( cit != iv_idNonMaximalTypeIndexes[type].end() );
// composite index already exists
result = (*cit).second;
}
assert( EXISTS(result) );
return *result;
}
bool IndexRepository::contains(TyFS tyFS) const {
assert( iv_bIsInitialized );
TyFSType tyType = iv_rFSHeap.getType(tyFS);
vector<internal::SingleIndex*> const & crSingleIndexes = getAllSingleIndexesForType(tyType);
vector<internal::SingleIndex*>::const_iterator cit;
for (cit = crSingleIndexes.begin(); cit != crSingleIndexes.end(); ++cit) {
if ( (*cit)->contains(tyFS) ) {
return true;
}
}
return false;
}
void IndexRepository::add(TyFS fs) {
assert( iv_bIsInitialized );
TyFSType type = iv_rFSHeap.getType(fs);
assert( iv_rFSHeap.getTypeSystem().isValidType(type) );
UIMA_TPRINT("Adding fs of type " << iv_rFSHeap.getTypeSystem().getTypeName(type) << ": " << (int) fs);
assert( type < iv_cacheDirtyFlags.size() );
iv_cacheDirtyFlags[type].clear();
assert( type < iv_indexes.size() );
vector<internal::SingleIndex*>& typeIndexes = iv_indexes[type];
if (!iv_isUsed[type]) {
//if there is no index defined for this type
if (typeIndexes.size() == 0 ) {
iv_undefinedindex.push_back(fs);
return;
}
iv_isUsed[type] = true;
iv_usedIndexes.push_back(type);
}
// for all single indexes on the type of fs
vector<internal::SingleIndex*>::iterator it;
for (it = typeIndexes.begin(); it != typeIndexes.end(); ++it) {
UIMA_TPRINT("index type: " << (*it)->getType());
UIMA_TPRINT(" (" << iv_rFSHeap.getTypeSystem().getTypeName( (*it)->getType() ));
assert( iv_rFSHeap.getTypeSystem().isValidType( (*it)->getType() ));
assert( (*it)->getType() == type );
(*it)->add(fs);
}
}
void IndexRepository::clearDirtyFlagForIndex(IndexABase const * index) {
assert(EXISTS(index) );
TyFSType t = index->getType();
assert( iv_indexDefinition.getTypeSystem().isValidType(t) );
vector<TyFSType> types;
iv_indexDefinition.getTypeSystem().getSubsumedTypes(t, types);
vector<TyFSType>::const_iterator cit;
for (cit = types.begin(); cit != types.end(); ++cit) {
assert( (*cit) < iv_cacheDirtyFlags.size() );
set<IndexABase const *> & rIndexSet = iv_cacheDirtyFlags[*cit];
rIndexSet.insert(index);
}
}
bool IndexRepository::isDirtyForIndex(IndexABase const * index) const {
assert(EXISTS(index) );
TyFSType t = index->getType();
assert( iv_indexDefinition.getTypeSystem().isValidType(t) );
vector<TyFSType> types;
iv_indexDefinition.getTypeSystem().getSubsumedTypes(t, types);
vector<TyFSType>::const_iterator cit;
for (cit = types.begin(); cit != types.end(); ++cit) {
assert( (*cit) < iv_cacheDirtyFlags.size() );
set<IndexABase const *> const & crIndexSet = iv_cacheDirtyFlags[*cit];
if ( crIndexSet.find(index) == crIndexSet.end() ) {
return true;
}
}
return false;
}
/*************************************************************/
#ifndef NDEBUG
void IndexRepository::print(ostream& os) const {
os << "===========================================" << endl;
size_t i,j;
for (i=1; i<iv_indexes.size(); ++i) {
UIMA_TPRINT("index for type: " << i);
assert( iv_indexDefinition.getTypeSystem().isValidType(i) );
os << "Index for type " << iv_indexDefinition.getTypeSystem().getTypeName(i) << ":" << endl;
for (j=0; j<iv_indexes[i].size(); ++j) {
os << " " << j << "th index: ";
IndexABase* ix = iv_indexes[i][j];
IndexIterator* it = ix->createIterator();
for (it->moveToFirst(); it->isValid(); it->moveToNext() ) {
os << (size_t) it->get() << " ";
}
os << endl;
delete it;
}
}
os << "===========================================" << endl;
}
#endif
}
}
/* ----------------------------------------------------------------------- */