blob: 212c24a45b254f928f9214d5c415e0b0f3c1fc74 [file] [log] [blame]
/** \file lowlevel_fsheap.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"
//#define DEBUG_VERBOSE
#include "uima/macros.h"
#include "uima/lowlevel_fsheap.hpp"
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
using namespace std;
namespace uima {
namespace lowlevel {
TyFS const FSHeap::INVALID_FS = 0;
FSHeap::FSHeap(TypeSystem const & rclTypeSystem,
size_t uiFSHeapPageSize,
size_t uiStringHeapPageSize,
size_t uiStringRefHeapPageSize) :
iv_clTemporaryHeap(uiFSHeapPageSize, 0),
iv_clTemporaryStringHeap(uiStringHeapPageSize, 0),
iv_clTemporaryStringRefHeap(uiStringRefHeapPageSize, 0),
iv_clTemporary8BitHeap(1, 0),
iv_clTemporary16BitHeap(1, 0),
iv_clTemporary64BitHeap(1, 0),
iv_rclTypeSystem(rclTypeSystem) {
UIMA_TPRINT("heap constructed");
assert( INVALID_FS == 0 );
}
FSHeap::FSHeap(TypeSystem const & rclTypeSystem,
size_t uiFSHeapPageSize,
size_t uiStringHeapPageSize,
size_t uiStringRefHeapPageSize,
size_t uiMinHeapPageSize) :
iv_clTemporaryHeap(uiFSHeapPageSize, 0),
iv_clTemporaryStringHeap(uiStringHeapPageSize, 0),
iv_clTemporaryStringRefHeap(uiStringRefHeapPageSize, 0),
iv_clTemporary8BitHeap(uiMinHeapPageSize, 0),
iv_clTemporary16BitHeap(uiMinHeapPageSize, 0),
iv_clTemporary64BitHeap(uiMinHeapPageSize, 0),
iv_rclTypeSystem(rclTypeSystem) {
UIMA_TPRINT("heap constructed");
assert( INVALID_FS == 0 );
}
FSHeap::~FSHeap() {}
void FSHeap::reset() {
assert( debugIsConsistent() );
TyFSHeap & rHeapToBeResetted = getHeap();
rHeapToBeResetted.reset();
TyStringHeap & rStringHeapToBeResetted = getStringHeap();
rStringHeapToBeResetted.reset();
TyStringRefHeap & rStringRefHeapToBeResetted = getStringRefHeap();
rStringRefHeapToBeResetted.reset();
Ty8BitHeap & r8BitHeapToBeResetted = get8BitHeap();
r8BitHeapToBeResetted.reset();
Ty16BitHeap & r16BitHeapToBeResetted = get16BitHeap();
r16BitHeapToBeResetted.reset();
Ty64BitHeap & r64BitHeapToBeResetted = get64BitHeap();
r64BitHeapToBeResetted.reset();
}
void FSHeap::setStringValue(TyFS tyFs, TyFSFeature tyFeature, int strRef) {
assert( iv_rclTypeSystem.isValidFeature(tyFeature) );
assert( iv_rclTypeSystem.subsumes(uima::internal::gs_tyStringType, iv_rclTypeSystem.getRangeType(tyFeature)));
#ifndef NDEBUG
TyFSType rangeType = iv_rclTypeSystem.getRangeType(tyFeature);
// if we have an enumeration subtype of string
if (rangeType != uima::internal::gs_tyStringType ) {
vector<icu::UnicodeString> const & crStringSet = iv_rclTypeSystem.getStringsForStringSubtype(rangeType);
vector<icu::UnicodeString>::const_iterator cit;
bool bStringFound = false;
UnicodeStringRef crStringRef(iv_clTemporaryStringHeap.getHeapStart()+strRef);
for (cit = crStringSet.begin(); cit != crStringSet.end(); ++cit) {
UnicodeStringRef ref(*cit);
if ( ref == crStringRef ) {
bStringFound = true;
break;
}
}
assert (bStringFound);
}
#endif
TyFS tyCurrentString = getFeatureInternal( tyFs, tyFeature );
if (tyCurrentString == 0) {
// add entry to StringRefHeap and set values there
tyCurrentString = getStringAsFS(strRef);
} else {
// reuse entry in StringRefHeap
setStringRef(tyCurrentString, strRef);
}
setFeatureInternal(tyFs, tyFeature, tyCurrentString);
}
void FSHeap::copyFeatures(TyFS tyTarget, TyFS tySource, size_t featNum) {
uima::lowlevel::TyFSType type = getType(tyTarget);
if (featNum == 0) {
assert( type == getType(tySource) );
featNum = iv_rclTypeSystem.getFeatureNumber( getType(tyTarget));
}
size_t i;
for (i=1; i<=featNum; ++i) {
uima::lowlevel::TyFSFeature feat = iv_rclTypeSystem.getFeatureFromOffset(type, i);
if ( iv_rclTypeSystem.subsumes( uima::internal::gs_tyStringType, iv_rclTypeSystem.getRangeType(feat) ) ) {
// get offset of stringRef in stringRefHeap
int strRef = iv_clTemporaryHeap.getHeapValue(tySource+i);
// if string value set, create duplicate reference to string in refHeap
if (strRef != 0) {
int ref = iv_clTemporaryStringRefHeap.getHeapValue(1 + 2*(strRef-1));
iv_clTemporaryHeap.setHeapValue(tyTarget+i, getStringAsFS(ref));
}
} else {
iv_clTemporaryHeap.setHeapValue(tyTarget+i, iv_clTemporaryHeap.getHeapValue(tySource+i));
}
}
}
// cout << of a 64bit type causes a warning (conversion to int, loss of data)
// since we can't help the implementation of cout we surpress the warning
#if defined( _MSC_VER )
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif
void FSHeap::printFS(ostream& os, TyFS fs) const {
TyFSType type = getType( fs );
icu::UnicodeString typeName = iv_rclTypeSystem.getTypeName(type);
int n=0;
os << n++ << ": | " << typeName << endl;
unsigned int i;
for (i=1; i<iv_rclTypeSystem.getFeatureNumber(type) + 1; ++i) {
os << n++ << ": | " << (ptrdiff_t) getFeatureWithOffset(fs, i) << endl;
}
}
void FSHeap::print(ostream& os) const {
os << "=============================================" << endl;
#ifdef BYEBYEPTRS
void * h;
size_t i;
size_t lastHeapCell = iv_clTemporaryHeap.getLastHeapCell();
size_t topOfHeap = iv_clTemporaryHeap.getTopOfHeap();
if (true) {
os << "Plain HEAP:" << endl;
h=iv_clTemporaryHeap.getHeapStart();
i=0;
for (h=1; h< lastHeapCell; ++h) {
os << i++ << " (" << (ptrdiff_t) h << ", " << h << ") : | " << ((ptrdiff_t) (*h));
if (h == topOfHeap) {
os << " <---" << endl;
break;
}
os << endl;
}
}
os << "-----------------------------" << endl;
UChar* uc = iv_clTemporaryStringHeap.getHeapStart();
size_t topOfStringHeap = iv_clTemporaryStringHeap.getTopOfHeap();
if (false) {
os << "PLAIN STRING TABLE" << endl;
while ((uc-iv_clTemporaryStringHeap.getHeapStart())<topOfStringHeap) {
os << (ptrdiff_t) uc << ": " << *uc << "(" << (ptrdiff_t) (*uc) << ")" << endl;
++uc;
}
os << "-----------------------------" << endl;
uc = iv_clTemporaryStringHeap.getHeapStart();
topOfStringHeap = iv_clTemporaryStringHeap.getTopOfHeap();
}
os << "String table: " << endl;
while ( (uc-iv_clTemporaryStringHeap.getHeapStart()) < topOfStringHeap) {
UnicodeStringRef uls(uc);
os << " " << (ptrdiff_t) uc << ": " << uls << endl;
uc += uls.length() + 1;
}
os << "-----------------------------" << endl;
os << "HEAP:" << endl;
h = iv_clTemporaryHeap.getHeapStart() + 1;
int n=1;
while (h<lastHeapCell) {
if ( (*h) == 0 ) {
return;
}
TyFS currentFS = h;
TyFSType type = getType( h );
icu::UnicodeString typeName = iv_rclTypeSystem.getTypeName(type);
os << n++ << ": (" << (ptrdiff_t) h << ")| " << typeName << endl;
++h;
int i;
for (i=0; i< (int) iv_rclTypeSystem.getFeatureNumber(type); ++i) {
os << n++ << ": (" << (ptrdiff_t) h << ")| " << ((ptrdiff_t) (*h)) << endl;
++h;
}
if (iv_rclTypeSystem.subsumes( uima::internal::gs_tyArrayBaseType, type) ) {
++h; // for the array size field
int iArraySize = getArraySize(currentFS);
for (i=0; i<iArraySize; ++i) {
os << n++ << ": (" << (ptrdiff_t) h << ")| " << ((ptrdiff_t) (*h)) << endl;
++h;
}
}
}
#endif
}
#if defined( _MSC_VER )
#pragma warning( pop )
#endif
#ifdef ASSERT_OR_RETURN_FALSE
#error ASSERT_OR_RETURN_FALSE already defined
#endif
#define ASSERT_OR_RETURN_FALSE(x) if (!(x)) return false
//#define ASSERT_OR_RETURN_FALSE(x) assert(x)
bool FSHeap::debugIsConsistent() const {
#ifdef BYEBYEPTRS
if (iv_clTemporaryHeap.getSegmentNumber() >= 1) {
return true;
}
// print(cout);
static int debugCheck = 0;
// cerr << " debugCheck: " << debugCheck << endl;
++debugCheck;
if ( (debugCheck % 1) != 0) {
// return true;
}
UIMA_TPRINT(" doing check... (debugCheck: " << debugCheck << ")");
TyFSType integerType = iv_rclTypeSystem.getTypeByName("uima.cas.Integer");
TyFSType floatType = iv_rclTypeSystem.getTypeByName("uima.cas.Float");
TyFSType stringType = iv_rclTypeSystem.getTypeByName("uima.cas.String");
size_t lastHeapCell = iv_clTemporaryHeap.getLastHeapCell();
size_t h = 1;
while (h<lastHeapCell) {
UIMA_TPRINT("Checking heap cell " << ((lastHeapCell-h)) );
ASSERT_OR_RETURN_FALSE( EXISTS(h) );
ASSERT_OR_RETURN_FALSE( debugIsValidHeapCell(h) );
if ( (*h) == 0) {
do {
ASSERT_OR_RETURN_FALSE( (*h) == 0 );
++h;
} while (h<lastHeapCell);
UIMA_TPRINT(" check done");
return true;
}
ASSERT_OR_RETURN_FALSE( *h != 0 );
TyFSType type = getType( h );
ASSERT_OR_RETURN_FALSE( type != 0 );
vector<TyFSFeature> features;
iv_rclTypeSystem.getAppropriateFeatures(type, features);
ASSERT_OR_RETURN_FALSE( features.size() == iv_rclTypeSystem.getFeatureNumber(type) );
size_t i;
for (i=0; i<features.size(); ++i) {
TyFSFeature f = features[i];
TyFSType rangeType = iv_rclTypeSystem.getRangeType( f );
if ( (rangeType == integerType)
|| (rangeType == floatType)
|| iv_rclTypeSystem.subsumes(stringType, rangeType) ) {}
else {
if (!isUntouchedFSValue(h,f)) {
// type is complex FS
TyFS fs = getFSValue(h, f);
ASSERT_OR_RETURN_FALSE(debugIsValidHeapCell(fs));
TyFSType fsType = getType(fs);
ASSERT_OR_RETURN_FALSE( iv_rclTypeSystem.subsumes(rangeType, fsType) );
}
}
}
h += features.size() + 1;
}
#endif
UIMA_TPRINT(" check done");
return true;
}
bool FSHeap::debugIsValidHeapCell(TyHeapCell cell) const {
return iv_clTemporaryHeap.debugIsValidHeapCell(cell);
}
}
}
/* ----------------------------------------------------------------------- */