blob: 7826fb06a1a8d62419495272ba6d3643547a4676 [file] [log] [blame]
/** \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;
}
}
}