| /** \file lowlevel_indexdfinition.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: |
| |
| ----------------------------------------------------------------------------- |
| |
| |
| -------------------------------------------------------------------------- */ |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Include dependencies */ |
| /* ----------------------------------------------------------------------- */ |
| #include "uima/pragmas.hpp" |
| |
| #include "uima/msg.h" |
| #include "uima/engine.hpp" |
| #include "uima/lowlevel_indexdefinition.hpp" |
| #include "uima/lowlevel_internal_indexfactory.hpp" |
| /* ----------------------------------------------------------------------- */ |
| /* Constants */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Forward declarations */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Types / Classes */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Implementation */ |
| /* ----------------------------------------------------------------------- */ |
| using namespace std; |
| namespace uima { |
| namespace lowlevel { |
| |
| IndexDefinition::IndexDefinition(uima::lowlevel::TypeSystem const & typeSystem) |
| : iv_crTypeSystem(typeSystem), |
| iv_bIsCommitted(false) { |
| } |
| |
| IndexDefinition::~IndexDefinition() { |
| clear(); |
| } |
| |
| void IndexDefinition::clear() { |
| size_t i; |
| // delete factories |
| map<TyIndexID, internal::IndexFactory*>::iterator factoryIterator; |
| for (factoryIterator = iv_mapFactories.begin(); factoryIterator != iv_mapFactories.end(); ++factoryIterator) { |
| delete (*factoryIterator).second; |
| } |
| |
| // delete comparators |
| for (i=0; i<iv_vecComparators.size(); ++i) { |
| delete iv_vecComparators[i]; |
| iv_vecComparators[i] = NULL; |
| } |
| iv_mapFactories.clear(); |
| iv_mapIndexTypes.clear(); |
| iv_mapIsPermanentFlags.clear(); |
| iv_vecComparators.clear(); |
| iv_bIsCommitted = false; |
| } |
| |
| void IndexDefinition::reset() { |
| clear(); |
| } |
| |
| |
| bool IndexDefinition::isValidIndexId(IndexDefinition::TyIndexID const & crID, TyFSType tyType) const { |
| return isValidIndexId(crID) && iv_crTypeSystem.subsumes( getTypeForIndex(crID), tyType); |
| } |
| |
| /** |
| * This method chooses the suitable factory depending on the index kind. |
| */ |
| internal::IndexFactory * IndexDefinition::createFactory(EnIndexKind enIxKind, TyFSType tyType, IndexComparator const * pComparator) const { |
| assert( !iv_bIsCommitted ); |
| internal::IndexFactory * pResult = NULL; |
| switch (enIxKind) { |
| case enOrdered: { |
| assert( iv_crTypeSystem.subsumes( pComparator->getType(), tyType ) ); |
| pResult = new internal::OrderedIndexFactory(pComparator); |
| break; |
| } |
| case enSet: { |
| assert( iv_crTypeSystem.subsumes( pComparator->getType(), tyType ) ); |
| pResult = new internal::SetIndexFactory(pComparator); |
| break; |
| } |
| case enFIFO: { |
| pResult = new uima::lowlevel::internal::FIFOIndexFactory(tyType); |
| break; |
| } |
| default: |
| assert(false); |
| |
| } |
| assert( pResult != NULL ); |
| return pResult; |
| } |
| |
| |
| |
| void IndexDefinition::defineIndex(EnIndexKind enIxKind, |
| TyFSType tyType, |
| vector<uima::lowlevel::TyFSFeature> const & crKeyFeatures, |
| vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> const & crComparators, |
| IndexDefinition::TyIndexID const & crID, |
| bool bIsPermanent) { |
| assert(!iv_bIsCommitted); |
| // if index does not yet exist |
| if (! isValidIndexId(crID)) { |
| // create comparator |
| assert( crKeyFeatures.size() == crComparators.size() ); |
| uima::lowlevel::IndexComparator * pComparator = new uima::lowlevel::IndexComparator(*this, tyType); |
| assert( EXISTS(pComparator) ); |
| |
| size_t i; |
| for (i=0; i<crKeyFeatures.size(); ++i) { |
| pComparator->addKey(crKeyFeatures[i], crComparators[i]); |
| } |
| iv_vecComparators.push_back(pComparator); |
| |
| // create factory with the comparator |
| internal::IndexFactory* pFactory = createFactory(enIxKind, tyType, pComparator); |
| assert( pFactory != NULL ); |
| |
| // register factory for index ID |
| UIMA_TPRINT("creating index"); |
| assert( iv_mapFactories.find(crID) == iv_mapFactories.end() ); |
| iv_mapFactories[crID] = pFactory; |
| assert( iv_crTypeSystem.subsumes( pFactory->getType(), tyType ) ); |
| assert( iv_mapIndexTypes.find(crID) == iv_mapIndexTypes.end() ); |
| |
| // register type for index ID |
| iv_mapIndexTypes[crID] = tyType; |
| |
| // register if index is contains permanent FSs |
| assert( iv_mapIsPermanentFlags.find(crID) == iv_mapIsPermanentFlags.end() ); |
| iv_mapIsPermanentFlags[crID] = bIsPermanent; |
| } else { |
| // check if index is compatible with existing one |
| UIMA_TPRINT(" An index with ID " << crID << " already exists, checking if it is compatible"); |
| |
| if (! isCompatibleIndexDefinition( enIxKind, tyType, crKeyFeatures, crComparators, crID, bIsPermanent) ) { |
| UIMA_EXC_THROW_NEW(IncompatibleIndexDefinitionsException, |
| UIMA_ERR_INCOMPATIBLE_INDEX_DEFINITIONS, |
| ErrorMessage(UIMA_MSG_ID_EXC_INCOMPATIBLE_INDEX_DEFINITIONS, crID), |
| UIMA_MSG_ID_EXCON_CREATING_INDEXES_FROM_CONFIG, |
| ErrorInfo::recoverable); |
| } |
| |
| |
| } |
| } |
| |
| void IndexDefinition::commit() { |
| iv_bIsCommitted = true; |
| } |
| |
| uima::lowlevel::IndexComparator const * IndexDefinition::getComparator(IndexDefinition::TyIndexID const & crID) const { |
| assert( isValidIndexId(crID) ); |
| map<IndexDefinition::TyIndexID, uima::lowlevel::internal::IndexFactory*>::const_iterator cit; |
| cit = iv_mapFactories.find(crID); |
| uima::lowlevel::internal::IndexFactory const * pFactory = (*cit).second; |
| assert( EXISTS(pFactory) ); |
| uima::lowlevel::IndexComparator const * cpResult = pFactory->getComparator(); |
| #ifndef NDEBUG |
| if ( getIndexKind(crID) == enFIFO ) { |
| assert( cpResult == NULL ); |
| } else { |
| assert( EXISTS(cpResult) ); |
| } |
| #endif |
| return cpResult; |
| } |
| |
| IndexDefinition::EnIndexKind IndexDefinition::getIndexKind(IndexDefinition::TyIndexID const & crID) const { |
| assert( isValidIndexId(crID) ); |
| map<IndexDefinition::TyIndexID, uima::lowlevel::internal::IndexFactory*>::const_iterator cit; |
| cit = iv_mapFactories.find(crID); |
| uima::lowlevel::internal::IndexFactory const * pFactory = (*cit).second; |
| assert( EXISTS(pFactory) ); |
| return pFactory->getIndexKind(); |
| } |
| |
| void IndexDefinition::getAllIndexIDs(vector<IndexDefinition::TyIndexID>& rResult) const { |
| rResult.clear(); |
| map<IndexDefinition::TyIndexID, TyFSType>::const_iterator cit; |
| for (cit = iv_mapIndexTypes.begin(); cit != iv_mapIndexTypes.end(); ++cit) { |
| rResult.push_back( (*cit).first ); |
| } |
| } |
| |
| |
| bool IndexDefinition::isCompatibleIndexDefinition(EnIndexKind enIxKind, |
| TyFSType tyType, |
| vector<uima::lowlevel::TyFSFeature> const & crKeyFeatures, |
| vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> const & crComparators, |
| IndexDefinition::TyIndexID const & crID, |
| bool ) const { |
| assert(isValidIndexId(crID)); |
| |
| if (getIndexKind(crID) != enIxKind) { |
| UIMA_TPRINT("Wrong index kind!"); |
| return false; |
| } |
| if (getTypeForIndex(crID) != tyType) { |
| UIMA_TPRINT("Wrong index type!"); |
| return false; |
| } |
| uima::lowlevel::IndexComparator const * cpComp = getComparator(crID); |
| if (cpComp != NULL) { |
| assert( (enIxKind == enOrdered) || (enIxKind == enSet) ); |
| assert( cpComp->getType() == tyType ); |
| |
| if (crKeyFeatures.size() != cpComp->getKeyFeatures().size()) { |
| UIMA_TPRINT("key feature length different, number of key features: " << crKeyFeatures.size() |
| << ", existing key feature length: " << cpComp->getKeyFeatures().size()); |
| return false; |
| } |
| if (crKeyFeatures != cpComp->getKeyFeatures()) { |
| UIMA_TPRINT("Wrong key features!"); |
| return false; |
| } |
| if (crComparators != cpComp->getComparisonOps() ) { |
| UIMA_TPRINT("Wrong comparison ops!"); |
| return false; |
| } |
| } else { |
| assert( enIxKind == enFIFO ); |
| } |
| return true; |
| } |
| |
| } |
| } |
| |
| |
| |
| |