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