| /** \file lowlevel_indexcomparator.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 */ |
| /* ----------------------------------------------------------------------- */ |
| //#define DEBUG_VERBOSE |
| |
| #include "uima/pragmas.hpp" |
| |
| #include "uima/macros.h" |
| #include "uima/lowlevel_indexcomparator.hpp" |
| #include "uima/lowlevel_indexdefinition.hpp" |
| /* ----------------------------------------------------------------------- */ |
| /* Constants */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Forward declarations */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Types / Classes */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Implementation */ |
| /* ----------------------------------------------------------------------- */ |
| using namespace std; |
| namespace uima { |
| namespace lowlevel { |
| |
| IndexComparator::IndexComparator(IndexDefinition const & indexDefinition, |
| TyFSType tyType, |
| vector<TyFSFeature> const & crIndexs) |
| : iv_indexDefinition( indexDefinition), |
| iv_tyType(tyType) { |
| size_t i; |
| for (i=0; i<crIndexs.size(); ++i) { |
| addKey(crIndexs[i], STANDARD_COMPARE); |
| } |
| } |
| |
| IndexComparator::IndexComparator(IndexDefinition const & indexDefinition, |
| TyFSType tyType) |
| : iv_indexDefinition( indexDefinition), |
| iv_tyType(tyType) { |
| } |
| |
| |
| void IndexComparator::addKey(TyFSFeature tyFeature, |
| EnKeyFeatureComp enComp) { |
| TypeSystem const & crTypeSystem = iv_indexDefinition.getTypeSystem(); |
| assert( crTypeSystem.isValidType(iv_tyType) ); |
| |
| // if this key is type priority |
| if (tyFeature == uima::lowlevel::TypeSystem::INVALID_FEATURE) { |
| iv_features.push_back(uima::lowlevel::TypeSystem::INVALID_FEATURE); |
| iv_offsets.push_back(0); |
| iv_appropTypes.push_back(BUILTIN_TYPE_INVALID); |
| } else { |
| assert( crTypeSystem.isAppropriateFeature(iv_tyType, tyFeature) ); |
| iv_features.push_back(tyFeature); |
| iv_offsets.push_back( crTypeSystem.getFeatureOffset(tyFeature) ); |
| TyFSType tyAppropType = crTypeSystem.getRangeType(tyFeature); |
| |
| if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_INTEGER)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_INTEGER ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_FLOAT)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_FLOAT ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_STRING)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_STRING ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_BOOLEAN)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_BOOLEAN ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_BYTE)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_BYTE ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_SHORT)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_SHORT ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_LONG)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_LONG ); |
| } else if (tyAppropType == crTypeSystem.getTypeByName( CAS::TYPE_NAME_DOUBLE)) { |
| iv_appropTypes.push_back( BUILTIN_TYPE_DOUBLE); |
| } |
| else { |
| assertWithMsg(false, "Type not supported for key features!"); |
| } |
| } |
| iv_comparators.push_back(enComp); |
| |
| assert( iv_offsets.size() == iv_appropTypes.size() ); |
| assert( iv_offsets.size() == iv_features.size() ); |
| assert( iv_offsets.size() == iv_comparators.size() ); |
| } |
| |
| inline int |
| inline_strCompare(const UChar *s1, size_t length1, |
| const UChar *s2, size_t length2) { |
| const UChar *limit1; |
| UChar c1, c2; |
| |
| /* memcmp/UnicodeString style, both length-specified */ |
| int lengthResult; |
| |
| /* limit1=s1+min(lenght1, length2) */ |
| if (length1<length2) { |
| lengthResult=-1; |
| limit1=s1+length1; |
| } else if (length1==length2) { |
| lengthResult=0; |
| limit1=s1+length1; |
| } else { /* length1>length2 */ |
| lengthResult=1; |
| limit1=s1+length2; |
| } |
| |
| if (s1==s2) { |
| return lengthResult; |
| } |
| |
| for (;;) { |
| /* check pseudo-limit */ |
| if (s1==limit1) { |
| return lengthResult; |
| } |
| |
| c1=*s1; |
| c2=*s2; |
| if (c1!=c2) { |
| break; |
| } |
| ++s1; |
| ++s2; |
| } |
| |
| return(int)c1-(int)c2; |
| } |
| |
| int IndexComparator::compare(uima::lowlevel::FSHeap const & heap, TyFS fs1, TyFS fs2) const { |
| if (fs1 == fs2) { |
| return 0; |
| } |
| assert( heap.getTypeSystem().subsumes( iv_tyType, heap.getType(fs1)) ); |
| assert( heap.getTypeSystem().subsumes( iv_tyType, heap.getType(fs2)) ); |
| UIMA_TPRINT("Comparing fs of type " << heap.getTypeSystem().getTypeName( heap.getType(fs1))); |
| UIMA_TPRINT(" with fs of type " << heap.getTypeSystem().getTypeName( heap.getType(fs2))); |
| bool isGreater = false; |
| bool isLess = false; |
| size_t i; |
| const size_t uiOffsetsSize = iv_offsets.size(); |
| TyFeatureOffset utCurrentOffset; |
| // for each feature |
| for (i=0; i <uiOffsetsSize; ++i) { |
| UIMA_TPRINT("Comparing feature " << i); |
| utCurrentOffset = iv_offsets[i]; |
| // if type priority |
| if (utCurrentOffset == 0) { |
| assert( iv_features[i] == uima::lowlevel::TypeSystem::INVALID_FEATURE ); |
| |
| uima::lowlevel::TyFSType t1 = heap.getType(fs1); |
| uima::lowlevel::TyFSType t2 = heap.getType(fs2); |
| |
| uima::lowlevel::TypeSystem const & crTypeSystem = heap.getTypeSystem(); |
| if (t1 == t2) { |
| isLess = false; |
| isGreater = false; |
| } else if (crTypeSystem.hasPriorityOver(t1, t2)) { |
| isLess = true; |
| isGreater = false; |
| } else { |
| isLess = false; |
| isGreater = true; |
| } |
| } else { |
| TyFS val1 = heap.getFeatureWithOffset(fs1, utCurrentOffset); |
| TyFS val2 = heap.getFeatureWithOffset(fs2, utCurrentOffset); |
| switch (iv_appropTypes[i]) { |
| case BUILTIN_TYPE_INTEGER: { |
| int i1 = FSHeap::getFSAsInt(val1); |
| int i2 = FSHeap::getFSAsInt(val2); |
| UIMA_TPRINT(" val1: " << i1 << ", val2: " << i2); |
| isLess = (i1 < i2); |
| isGreater = (i1 > i2); |
| break; |
| } |
| case BUILTIN_TYPE_FLOAT: { |
| float f1 = FSHeap::getFSAsFloat(val1); |
| float f2 = FSHeap::getFSAsFloat(val2); |
| isLess = (f1 < f2); |
| isGreater = (f1 > f2); |
| break; |
| } |
| case BUILTIN_TYPE_STRING: { |
| UnicodeStringRef us1 = heap.getFSAsString(val1); |
| UnicodeStringRef us2 = heap.getFSAsString(val2); |
| int iCmp = inline_strCompare(us1.getBuffer(), us1.length(), |
| us2.getBuffer(), us2.length()); |
| isLess = (iCmp < 0); |
| isGreater = (iCmp > 0); |
| break; |
| } |
| case BUILTIN_TYPE_BOOLEAN: { |
| bool f1 = FSHeap::getFSAsBoolean(val1); |
| bool f2 = FSHeap::getFSAsBoolean(val2); |
| isLess = (f1 < f2); |
| isGreater = (f1 > f2); |
| break; |
| } |
| case BUILTIN_TYPE_BYTE: { |
| char f1 = FSHeap::getFSAsByte(val1); |
| char f2 = FSHeap::getFSAsByte(val2); |
| isLess = (f1 < f2); |
| isGreater = (f1 > f2); |
| break; |
| } |
| case BUILTIN_TYPE_SHORT: { |
| short f1 = FSHeap::getFSAsShort(val1); |
| short f2 = FSHeap::getFSAsShort(val2); |
| isLess = (f1 < f2); |
| isGreater = (f1 > f2); |
| break; |
| } |
| case BUILTIN_TYPE_LONG: { |
| INT64 f1 = heap.getFSAsLong(val1); |
| INT64 f2 = heap.getFSAsLong(val2); |
| isLess = (f1 < f2); |
| isGreater = (f1 > f2); |
| break; |
| } |
| case BUILTIN_TYPE_DOUBLE: { |
| double f1 = heap.getFSAsDouble(val1); |
| double f2 = heap.getFSAsDouble(val2); |
| isLess = (f1 < f2); |
| isGreater = (f1 > f2); |
| break; |
| } |
| |
| default: |
| // UIMA_TPRINT("Unsupported type: " << heap.getTypeSystem().getTypeName(appropTypes[i])); |
| assertWithMsg(false, "Unsupported built-in type"); |
| } |
| } |
| UIMA_TPRINT(" isLess: " << isLess); |
| UIMA_TPRINT(" isGreater: " << isGreater); |
| assert( ! (isLess && isGreater) ); |
| |
| switch (iv_comparators[i]) { |
| case STANDARD_COMPARE: { |
| if (isLess) { |
| return 1; |
| } else { |
| if (isGreater) { |
| return -1; |
| } |
| } |
| break; |
| } |
| case REVERSE_STANDARD_COMPARE: { |
| if (isLess) { |
| return -1; |
| } else { |
| if (isGreater) { |
| return 1; |
| } |
| } |
| break; |
| } |
| default: |
| assert(false); |
| }; |
| } |
| return 0; |
| } |
| |
| |
| } |
| } |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| |
| |
| |