| /** \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 |
| |
| |
| } |
| } |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| |
| |