#include "mymalloc/mymalloc.h"
/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
*/
/*************************************************************
*
*
* PURPOSE:
* Tiles store BLOBTiles together with their type and
* their coordinates.
*
*
* COMMENTS:
* none
*
************************************************************/
static const char rcsid[] = "@(#)cachetamgr,Tile: $Id: tile.cc,v 1.79 2005/09/03 21:05:53 rasdev Exp $";
#include
#include "catalogmgr/ops.hh"
#include "tile.hh"
#include "relblobif/blobtile.hh"
#include "reladminif/adminif.hh"
#include "relblobif/inlinetile.hh"
#include "compression/tilecompression.hh"
#include "raslib/rmdebug.hh"
#include "raslib/miter.hh"
#include "raslib/miterf.hh"
#include "raslib/miterd.hh"
#include "raslib/basetype.hh"
#include
#ifdef RMANBENCHMARK
RMTimer Tile::opTimer("Tile","opTimer");
RMTimer Tile::relTimer("Tile","relTimer");
RMTimer Tile::o2Timer("Tile","o2Timer");
#endif
const Tile&
Tile::operator=(const Tile& tile)
{
if(this != &tile)
{
type = tile.type;
domain = tile.domain;
//cloning is faster than recreation
if (tile.compEngine != NULL) {
if(compEngine != NULL) {
delete compEngine;
}
compEngine = tile.compEngine->clone();
}
blobTile->resize(tile.blobTile->getSize());
blobTile->setDataFormat(tile.blobTile->getDataFormat());
blobTile->setCurrentFormat(tile.blobTile->getCurrentFormat());
memcpy(blobTile->getCells(), tile.blobTile->getCells(), blobTile->getSize());
setParameters(tile.getParameters());
}
return *this;
}
Tile::Tile(const Tile& tile)
: domain(tile.domain),
type(tile.type),
blobTile((DBTile*)NULL),
//cloning is faster than recreation
compEngine(NULL),
params(NULL)
{
if (tile.compEngine != NULL)
compEngine = tile.compEngine->clone();
if (RMInit::useTileContainer)
blobTile = new InlineTile(tile.blobTile->getSize(), tile.blobTile->getCells(), tile.blobTile->getDataFormat());
else
blobTile = new BLOBTile(tile.blobTile->getSize(), tile.blobTile->getCells(), tile.blobTile->getDataFormat());
blobTile->setCurrentFormat(tile.blobTile->getCurrentFormat());
setParameters(tile.getParameters());
}
Tile::Tile(std::vector* tilesVec)
: domain(),
type(NULL),
compEngine(NULL),
params(NULL),
blobTile((DBTile*)NULL)
{
// iterators for tiles
std::vector::iterator tileIt = tilesVec->begin();
std::vector::iterator tileEnd = tilesVec->end();
domain = (*(tileIt++))->getDomain();
while (tileIt != tilesVec->end())
{
domain.closure_with((*(tileIt++))->getDomain());
}
tileIt = tilesVec->begin();
// initialize type with type of first tile
type = (*tileIt)->getType();
if (RMInit::useTileContainer)
blobTile = new InlineTile(getSize(), (char)0, (*tileIt)->getDataFormat());
else
blobTile = new BLOBTile(getSize(), (char)0, (*tileIt)->getDataFormat());
// initialize compression with compression of first tile
//cloning is faster than recreation
if ((*tileIt)->compEngine != NULL)
compEngine = (*tileIt)->compEngine->clone();
setParameters((*tileIt)->getParameters());
// initialize domain
domain = (*(tileIt++))->getDomain();
while (tileIt != tileEnd)
domain.closure_with((*(tileIt++))->getDomain());
// insert all tiles in the result tile
tileIt = tilesVec->begin();
while (tileIt != tileEnd)
{
const r_Minterval& currDom = (*tileIt)->getDomain();
copyTile(currDom, (*tileIt), currDom);
tileIt++;
}
}
Tile::Tile(std::vector* tilesVec, const r_Minterval& resDom)
: params(NULL),
domain(resDom),
compEngine(NULL)
{
// iterators for tiles
std::vector::iterator tileIt;
// domain of the current tile
r_Minterval currDom;
// get first Tile
tileIt = tilesVec->begin();
// initialize type with type of first tile
type = (*tileIt)->getType();
// initialize compression with compression of first tile
//cloning is faster than recreation
if ((*tileIt)->compEngine != NULL)
compEngine = (*tileIt)->compEngine->clone();
setParameters((*tileIt)->getParameters());
// init contents
if (RMInit::useTileContainer)
blobTile = new InlineTile(getSize(), (char)0, (*tileIt)->getDataFormat());
else
blobTile = new BLOBTile(getSize(), (char)0, (*tileIt)->getDataFormat());
// insert all tiles in the result tile
tileIt = tilesVec->begin();
while (tileIt != tilesVec->end())
{
currDom = (*tileIt)->getDomain();
currDom.intersection_with(resDom);
copyTile(currDom, (*tileIt), currDom);
tileIt++;
}
}
Tile::Tile(const Tile* projTile, const r_Minterval& projDom, const std::set >* projDimSet)
: domain(projDom.dimension() - projDimSet->size()),
type(projTile->type),
compEngine(NULL),
params(NULL),
blobTile((DBTile*)NULL)
{
// calculate dimension of new Tile
r_Dimension dim = 0;
// pointer to cells in tile to be projected and new tile
char* cellTile = NULL;
char* cellProj = NULL;
for(dim = 0; dim < projDom.dimension(); dim++)
{
// do not include dimensions projected away
std::set >::const_iterator tempIt = projDimSet->find(dim);
if(tempIt == projDimSet->end())
{
domain << projDom[dim];
}
}
RMDBGONCE(3, RMDebug::module_tilemgr, "Tile", "domain result: " << domain << " domain original: " << projTile->getDomain());
// have to initialize the uncompressed contents in case an operation is called on the tile
//cloning is faster than recreation
if (projTile->compEngine)
compEngine = projTile->compEngine->clone();
setParameters(projTile->getParameters());
// init contents
if (RMInit::useTileContainer)
blobTile = new InlineTile(getSize(), (char)0, projTile->getDataFormat());
else
blobTile = new BLOBTile(getSize(), (char)0, projTile->getDataFormat());
// using r_Miter to iterate through tile to be projected and new tile.
r_Miter projTileIter(&projDom, &projTile->getDomain(), type->getSize(), (const char*)projTile->getContents());
r_Miter newTileIter(&domain, &domain, type->getSize(), blobTile->getCells());
// identity operation for base type, used for copying
UnaryOp* op = type->getUnaryOp(Ops::OP_IDENTITY, (BaseType*)type);
while(!projTileIter.isDone())
{
cellTile = newTileIter.nextCell();
cellProj = projTileIter.nextCell();
RMDBGONCE(3, RMDebug::module_tilemgr, "TransTile", "offset in original: " << (int)(cellProj-((Tile*)projTile)->getContents()) << " {" << (int)*cellProj << "} offset in result: " << (int)((int)(cellTile-getContents())) << " {" << (int)*cellTile << "}");
// execute operation on cell
(*op)(cellTile, cellProj);
}
delete op;
}
Tile::Tile(const r_Minterval& newDom, const BaseType* newType, DBTileId newBLOBTile)
: domain(newDom),
type(newType),
params(NULL),
compEngine(NULL),
blobTile(newBLOBTile)
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(" << newDom << ", " << newType->getName() << ", blob)");
}
Tile::Tile(const r_Minterval& newDom, const BaseType* newType, r_Data_Format newFormat)
: domain(newDom),
params(NULL),
type(newType),
compEngine(NULL),
blobTile((DBTile*)NULL)
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(new), size " << getSize());
// note that the size is not correct (usually too big) for compressed
// tiles. Doesn't matter, because resize is called anyway.
if (RMInit::useTileContainer)
blobTile = new InlineTile(getSize(), (char)0, newFormat);
else
blobTile = new BLOBTile(getSize(), (char)0, newFormat);
//not neccessary now
//initCompEngine();
}
Tile::Tile(const r_Minterval& newDom, const BaseType* newType, char* newCells, r_Bytes newSize, r_Data_Format newFormat)
: domain(newDom),
params(NULL),
type(newType),
compEngine(NULL),
blobTile((DBTile*)NULL)
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(), fmt " << newFormat << ", size " << newSize);
r_Data_Format current = r_Array;
if (!newSize)
{
// setting uncompressed contents
newSize = getSize();
}
else {
// setting compressed contents
current = newFormat;
}
if (RMInit::useTileContainer)
blobTile = new InlineTile(newSize, newCells, newFormat);
else
blobTile = new BLOBTile(newSize, newCells, newFormat);
blobTile->setCurrentFormat(current);
free(newCells);
//not neccessary now
//initCompEngine();
}
Tile::Tile(const r_Minterval& newDom, const BaseType* newType, const char* newCells, bool, r_Bytes newSize, r_Data_Format newFormat)
: domain(newDom),
params(NULL),
type(newType),
compEngine(NULL),
blobTile((DBTile*)NULL)
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","Tile(), fmt " << newFormat << ", size " << newSize);
r_Data_Format current = r_Array;
if (!newSize)
{
// setting uncompressed contents
newSize = getSize();
}
else {
// setting compressed contents
current = newFormat;
}
if (RMInit::useTileContainer)
blobTile = new InlineTile(newSize, newCells, newFormat);
else
blobTile = new BLOBTile(newSize, newCells, newFormat);
blobTile->setCurrentFormat(current);
// this one doesn't do this stupid thing: free(newCells);
//not neccessary now
//initCompEngine();
}
void
Tile::initCompEngine() const
{
if (compEngine == NULL)
{
char* typeStruct = type->getTypeStructure();
r_Base_Type *useType = (r_Base_Type*)(r_Type::get_any_type(typeStruct));
compEngine = r_Tile_Compression::create(blobTile->getDataFormat(), domain, useType);
delete useType;
free(typeStruct);
}
}
void
Tile::setCompressionFormat(r_Data_Format newFormat)
{
if (blobTile->getDataFormat() != newFormat)
{
decompress();
delete compEngine;
char* typeStruct = type->getTypeStructure();
r_Base_Type *useType = (r_Base_Type*)(r_Type::get_any_type(typeStruct));
compEngine = r_Tile_Compression::create(newFormat, domain, useType);
delete useType;
free(typeStruct);
blobTile->setDataFormat(newFormat);
}
}
void
Tile::setPersistent(bool state)
{
blobTile->setPersistent(state);
}
r_Bytes
Tile::getCompressedSize() const
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","getCompressedSize()");
compress();
return blobTile->getSize();
}
const char*
Tile::getCompressedContents() const
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile","getCompressedContents() const");
compress();
const char* cellPtr = blobTile->getCells();
return cellPtr;
}
bool
Tile::isPersistent() const
{
return blobTile->isPersistent();
}
Tile::~Tile()
{
RMDBGONCE(3, RMDebug::module_rasodmg, "Tile", "~Tile() " << (r_Ptr) this);
// this function has to check now if a tile has to be compressed.
// The old scheme of compression in AdminIf::compCompTiles does
// not work, because tiles may be destroyed before with releaseAll.
delete compEngine;
delete [] params;
}
DBTileId
Tile::getDBTile()
{
return blobTile;
}
char*
Tile::execCondenseOp(CondenseOp* myOp, const r_Minterval& areaOp)
{
RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execCondenseOp()");
char* cellOp = NULL;
char* dummy = getContents();
r_Miter opTileIter(&areaOp, &getDomain(), getType()->getSize(), dummy);
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
while(!opTileIter.isDone())
{
cellOp = opTileIter.nextCell();
// execute operation on cell
(*myOp)(cellOp);
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execCondenseOp()");
return myOp->getAccuVal();
}
void
Tile::execUnaryOp(UnaryOp* myOp, const r_Minterval& areaRes, const Tile* opTile, const r_Minterval& areaOp)
{
RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execUnaryOp()");
char* cellRes = NULL;
const char* cellOp = NULL;
char* dummy1 = getContents();
const char* dummy2 = opTile->getContents();
r_Miter resTileIter(&areaRes, &getDomain(), getType()->getSize(), dummy1);
r_Miter opTileIter(&areaOp, &opTile->getDomain(), opTile->getType()->getSize(), dummy2);
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
while(!resTileIter.isDone())
{
cellRes = resTileIter.nextCell();
cellOp = opTileIter.nextCell();
// execute operation on cell
(*myOp)(cellRes, cellOp);
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execUnaryOp()");
}
void
Tile::execBinaryOp(BinaryOp* myOp, const r_Minterval& areaRes, const Tile* op1Tile, const r_Minterval& areaOp1, const Tile* op2Tile, const r_Minterval& areaOp2)
{
if ( myOp == NULL )
{
throw r_Error (OPERANDSRESULTTYPESNOMATCH);
}
RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execBinaryOp()");
char* cellRes = NULL;
const char* cellOp1 = NULL;
const char* cellOp2 = NULL;
char* dummy1 = getContents();
const char* dummy2 = op1Tile->getContents();
const char* dummy3 = op2Tile->getContents();
r_Miter resTileIter(&areaRes, &getDomain(), getType()->getSize(), dummy1);
r_Miter op1TileIter(&areaOp1, &op1Tile->getDomain(), op1Tile->getType()->getSize(), dummy2);
r_Miter op2TileIter(&areaOp2, &op2Tile->getDomain(), op2Tile->getType()->getSize(), dummy3);
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
while(!resTileIter.isDone())
{
cellRes = resTileIter.nextCell();
cellOp1 = op1TileIter.nextCell();
cellOp2 = op2TileIter.nextCell();
// execute operation on cell
(*myOp)(cellRes, cellOp1, cellOp2);
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execBinaryOp()");
}
void
Tile::execConstOp(BinaryOp* myOp, const r_Minterval& areaRes, const Tile* opTile, const r_Minterval& areaOp, const char* cell, int constPos)
{
RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execConstOp()");
char* cellRes = NULL;
const char* cellOp = NULL;
char* dummy1 = getContents();
const char* dummy2 = opTile->getContents();
r_Miter resTileIter(&areaRes, &getDomain(), getType()->getSize(), dummy1);
r_Miter opTileIter(&areaOp, &opTile->getDomain(), opTile->getType()->getSize(), dummy2);
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
if (constPos == 1)
{
while(!resTileIter.isDone())
{
cellRes = resTileIter.nextCell();
cellOp = opTileIter.nextCell();
// execute operation on cell
(*myOp)(cellRes, cell, cellOp);
}
}
else {
while(!resTileIter.isDone())
{
cellRes = resTileIter.nextCell();
cellOp = opTileIter.nextCell();
// execute operation on cell
(*myOp)(cellRes, cellOp, cell);
}
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "execConstOp()");
}
void
Tile::execMarrayOp(MarrayOp* myOp, const r_Minterval& areaRes, const r_Minterval& areaOp)
{
r_Point pRes(areaRes.dimension());
r_Point pOp(areaOp.dimension());
int done = 0;
int recalc = 0;
int i = 0;
int j = 0;
int innerExtent = 0;
int resSize = 0;
int opSize = 0;
int dim = 0;
char* cellRes = NULL;
const char* cellOp = NULL;
// !!!! check, if areaRes is inside Tile
resSize = type->getSize();
dim = areaRes.dimension();
innerExtent = (areaOp.get_extent())[dim-1];
// initialize points
for(i = 0; i < areaRes.dimension(); i++)
{
pRes << areaRes[i].low();
pOp << areaOp[i].low();
}
cellRes = getCell(calcOffset(pRes));
// iterate over all cells
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
while(!done)
{
if(recalc)
{
cellRes = getCell(calcOffset(pRes));
recalc = 0;
}
(*myOp)(cellRes, pOp);
cellRes += resSize;
// increment coordinates
i = dim - 1;
++pRes[i];
++pOp[i];
while(pRes[i] > areaRes[i].high())
{
recalc = 1;
pRes[i] = areaRes[i].low();
pOp[i] = areaOp[i].low();
i--;
if(i < 0)
{
done = 1;
break;
}
++pRes[i];
++pOp[i];
}
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
}
char*
Tile::execGenCondenseOp(GenCondenseOp* myOp, const r_Minterval& areaOp)
{
r_Point pOp(areaOp.dimension());
int done = 0;
int i = 0;
int dim = areaOp.dimension();
// initialize points
for(i = 0; i < areaOp.dimension(); i++)
{
pOp << areaOp[i].low();
}
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
// iterate over all cells
while(!done)
{
(*myOp)(pOp);
// increment coordinates
i = dim - 1;
++pOp[i];
while(pOp[i] > areaOp[i].high())
{
pOp[i] = areaOp[i].low();
i--;
if(i < 0)
{
done = 1;
break;
}
++pOp[i];
}
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
return myOp->getAccuVal();
}
#ifdef RMANDEBUG
#define CHECK_ITER_SYNC(a,b) \
if (a.isDone() != b.isDone()) {RMDBGONCE(3, RMDebug::module_tilemgr, "Tile", "iterators out of sync!");}
#else
#define CHECK_ITER_SYNC(a,b)
#endif
template
static inline void tile_scale_core(r_Miter &iterDest, r_MiterFloat &iterSrc, T *dummy)
{
while (!iterDest.isDone())
{
const T* srcPtr = (const T*)iterSrc.nextCell();
T* destPtr = (T*)iterDest.nextCell();
*destPtr = *srcPtr;
CHECK_ITER_SYNC(iterSrc, iterDest)
}
CHECK_ITER_SYNC(iterSrc, iterDest)
}
#ifdef BLVAHELP
void fast_scale_resample_array(char *dest, const char *src, const r_Minterval &destIv, const r_Minterval &srcIv, const r_Minterval &iterDom, unsigned int type_len, unsigned int length)
{
r_MiterDirect destIter((void*)dest, destIv, destIv, type_len, 1);
r_MiterDirect subIter((void*)src, srcIv, iterDom, type_len, 1);
r_MiterDirect srcIter((void*)src, srcIv, iterDom, type_len, length);
unsigned int dim = (unsigned int)srcIv.dimension();
unsigned int i;
for (i=0; i= (long)length) rest = (long)length-1;
subIter.id[i].high = rest;
//count *= rest+1;
}
while (subIter.done == 0)
{
sum += *((const unsigned char*)(subIter.getData()));
++subIter;
count++;
}
cout<<"Sum="<& scaleFactors)
{
// origin is not used in this version
RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "execScaleOp()")
#ifdef BLVAHELP
fast_scale_resample_array((char*)getContents(),((Tile*)opTile)->getContents(), domain, opTile->getDomain(), sourceDomain, 1, 2);
#else
int typeLength = getType()->getSize();
const char *srcPtr = ((Tile*)opTile)->getContents();
r_MiterFloat iterSrc((Tile*)opTile, (r_Minterval&)sourceDomain, domain);
r_Miter iterDest(&domain, &domain, typeLength, getContents());
// optimize for common basetypes
switch (typeLength)
{
case 1:
tile_scale_core(iterDest, iterSrc, (char*)0);
break;
case 2:
tile_scale_core(iterDest, iterSrc, (short*)0);
break;
case 4:
tile_scale_core(iterDest, iterSrc, (long*)0);
break;
case 8:
tile_scale_core(iterDest, iterSrc, (double*)0);
break;
default:
while (!iterDest.isDone())
{
char *destPtr = iterDest.nextCell();
srcPtr = iterSrc.nextCell();
memcpy(destPtr, srcPtr, typeLength);
CHECK_ITER_SYNC(iterSrc, iterDest)
}
CHECK_ITER_SYNC(iterSrc, iterDest)
break;
}
#endif
RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "leaving Tile::execScaleOp()")
}
// the used version
int
Tile::scaleGetDomain(const r_Minterval& areaOp, const std::vector& scaleFactors, r_Minterval &areaScaled)
{
RMDBGENTER(2, RMDebug::module_tilemgr, "Tile", "scaleGetDomain() - second version")
try {
areaScaled= areaOp.create_scale(scaleFactors);
}
catch(r_Error& err) {
//error on scalling
RMDBGEXIT(2, RMDebug::module_tilemgr, "Tile", "scaleGetDomain(): areaOp = " << areaOp << " error performing scale")
return 0;
}
RMDBGEXIT(2, RMDebug::module_tilemgr, "Tile", "scaleGetDomain(): areaOp = " << areaOp << ", scaled = " << areaScaled)
return 1;
}
void
Tile::copyTile(const r_Minterval &areaRes, const Tile *opTile, const r_Minterval &areaOp)
{
RMDBGENTER(3, RMDebug::module_tilemgr, "Tile", "copyTile(" << areaRes << ", " << (r_Ptr)opTile << "," << areaOp << ")");
const char *cellOp = NULL;
char *cellRes = NULL;
// this may trigger decompression
cellOp = opTile->getContents();
cellRes = getContents();
r_Dimension dimRes = areaRes.dimension();
r_Dimension dimOp = areaOp.dimension();
r_Range width = areaRes[dimRes-1].get_extent();
if (width > areaOp[dimOp-1].get_extent())
{
width = areaOp[dimOp-1].get_extent();
RMInit::logOut << "RMDebug::module_tilemgr::copyTile() WARNING: had to adjust high dim width to " << width << endl;
}
unsigned int tsize = getType()->getSize();
unsigned int tsizeOp = opTile->getType()->getSize();
if (tsize != tsizeOp) {
RMDBGONCE(0, RMDebug::module_tilemgr, "Tile", "copyTile() ERROR: type sizes incompatible!"
<< endl << "this type: " << getType()->getName() << "(" << tsize << "), opTile type: "
<< opTile->getType()->getName() << "(" << tsizeOp << ")" );
// FIXME here we have to check if is appropiate to continue
}
// these iterators iterate last dimension first, i.e. minimal step size
r_MiterDirect resTileIter((void*)cellRes, getDomain(), areaRes, tsize);
r_MiterDirect opTileIter((void*)cellOp, opTile->getDomain(), areaOp, tsize);
#ifdef RMANBENCHMARK
opTimer.resume();
#endif
while (!resTileIter.isDone())
{
// copy entire line (continuous chunk in last dimension) in one go
memcpy(resTileIter.getData(), opTileIter.getData(), width * tsize);
// force overflow of last dimension
resTileIter.id[dimRes-1].pos += width;
opTileIter.id[dimOp-1].pos += width;
// iterate; the last dimension will always overflow now
++resTileIter;
++opTileIter;
}
#ifdef RMANBENCHMARK
opTimer.pause();
#endif
RMDBGEXIT(3, RMDebug::module_tilemgr, "Tile", "copyTile(" << areaRes << ", " << (r_Ptr)opTile << "," << areaOp << ")");
}
std::vector*
Tile::splitTile(r_Minterval resDom, int storageDomain)
{
// domain of current tile
r_Minterval currDom(resDom.dimension());
// type of result tiles
const BaseType* resType;
// iterators for tiles
std::vector* resultVec = new std::vector;
// pointer to generated current tile
Tile* smallTile;
// current factor for translating
r_Point cursor(resDom.dimension());
// origin of big tile
r_Point origin;
// size of result tiles
r_Point tileSize;
// flag
int done = 0;
// for loops
int i = 0;
// initialize cursor
for(i = 0; i < cursor.dimension(); i++)
cursor[i] = 0;
// calculate size of Tiles
tileSize = resDom.get_extent();
// initialize resType
resType = this->getType();
// origin of bigTile
origin = (this->getDomain()).get_origin();
// initialize currDom
for(i = 0; i < cursor.dimension(); i++)
currDom << r_Sinterval(origin[i], origin[i] + tileSize[i] - 1);
// resets resDom to lower left side of bigTile
resDom = currDom;
// intersect with bigTile
currDom.intersection_with(this->getDomain());
initCompEngine();
// iterate with smallTile over bigTile
while(!done)
{
currDom.intersection_with(this->getDomain());
// create new smallTile
smallTile = new Tile(currDom, resType, compEngine->get_data_format());
// fill it with relevant area
smallTile->copyTile(currDom, this, currDom);
// insert it in result vector
resultVec->push_back(smallTile);
// increment cursor, start with highest dimension
i = cursor.dimension() - 1;
cursor[i] += tileSize[i];
// move cursor
currDom = resDom.create_translation(cursor);
while(!(currDom.intersects_with(this->getDomain())))
{
cursor[i] = 0;
i--;
if(i < 0)
{
done = 1;
break;
}
cursor[i] += tileSize[i];
// move cursor
currDom = resDom.create_translation(cursor);
}
}
return resultVec;
}
void
Tile::printStatus(unsigned int level, std::ostream& stream) const
{
r_Point p(domain.dimension());
int done = 0;
int i = 0;
const char* cell;
int dim = domain.dimension();
// print the contents only on very high debug level
// initialize point
for(i = 0; i < dim; i++)
{
p << domain[i].low();
}
// iterate over all cells
while(!done)
{
// print cell
cell = getCell(calcOffset(p));
type->printCell(stream, cell);
// increment coordinate
i = dim - 1;
while(++p[i] > domain[i].high())
{
stream << endl;
p[i] = domain[i].low();
i--;
if(i < 0)
{
done = 1;
break;
}
}
if(i < (dim - 2)) stream << endl;
}
}
char*
Tile::getCell(const r_Point& aPoint)
{
r_Area cellOffset = domain.cell_offset(aPoint);
return getCell(cellOffset);
}
const char*
Tile::getCell(const r_Point& aPoint) const
{
r_Area cellOffset = domain.cell_offset(aPoint);
return getCell(cellOffset);
}
void
Tile::setCompressionEngine(r_Tile_Compression* newCompAlg)
{
decompress();
delete compEngine;
compEngine = newCompAlg;
blobTile->setDataFormat(compEngine->get_data_format());
}
const r_Minterval&
Tile::getDomain() const
{
return domain;
}
const BaseType*
Tile::getType() const
{
return type;
}
r_Dimension
Tile::getDimension() const
{
return domain.dimension();
}
r_Bytes
Tile::getSize() const
{
return domain.cell_count() * type->getSize();
}
r_Data_Format
Tile::getDataFormat() const
{
return blobTile->getDataFormat();
}
const char*
Tile::getCell(r_Area index) const
{
decompress();
return &(blobTile->getCells()[index * type->getSize()]);
}
char*
Tile::getCell(r_Area index)
{
decompress();
return &(blobTile->getCells()[index * type->getSize()]);
}
void
Tile::setCell(r_Area index, const char* newCell)
{
char* cells = getCell(index);
int typeSize = type->getSize();
for (int i = 0; i < typeSize; i++)
cells[i] = newCell[i];
}
char*
Tile::getContents()
{
decompress();
return blobTile->getCells();
}
const char*
Tile::getContents() const
{
decompress();
return blobTile->getCells();
}
void
Tile::setContents(char* newContents)
{
decompress();
blobTile->setCells(newContents);
}
void
Tile::setParameters(const char *par)
{
delete [] params;
if (par != NULL)
{
params = new char[strlen(par) + 1];
strcpy(params, par);
}
else
params = NULL;
}
const char*
Tile::getParameters() const
{
return params;
}
const r_Tile_Compression*
Tile::getCompressionEngine() const
{
return compEngine;
}
void
Tile::compress() const
{
if (blobTile->getCurrentFormat() != blobTile->getDataFormat())
{
initCompEngine();
r_ULong compressedSize = 0;
char* compressedData = (char*)(compEngine->compress(blobTile->getCells(), compressedSize, params));
if (!AdminIf::isReadOnlyTA())
{
r_ULong sizee = getSize();
if (compressedSize > sizee)
{
RMInit::logOut << "Warning: overriding compression setting(" << blobTile->getDataFormat() << ") to "
<< r_Array << " for tile " << getDomain()
<< " " << blobTile->getOId() << " because compressed size( " << compressedSize
<< " bytes) > uncompressed size( " << sizee << " bytes)" << endl;
r_Tile_Compression* compEngineN = r_Tile_Compression::create(r_Array, getDomain(), compEngine->get_base_type());
delete compEngine;
compEngine = compEngineN;
compEngineN = NULL;
((DBTile*)blobTile.ptr())->setDataFormat(compEngine->get_data_format());
free(compressedData);
compressedData = NULL;
compressedSize = sizee;
//not neccessary because already there
//blobTile->setNoModificationData(compressedData);
}
else {
blobTile->setNoModificationData(compressedData);
}
}
else {
blobTile->setNoModificationData(compressedData);
}
blobTile->setNoModificationSize(compressedSize);
blobTile->setCurrentFormat(compEngine->get_data_format());
}
}
bool
Tile::decompress() const
{
bool retval = true;
if (blobTile->getCurrentFormat() != r_Array)
{
initCompEngine();
bool wrongDecompress = false;
r_Bytes compressedSize = blobTile->getSize();
char* decompressedData = (char*)(compEngine->decompress(blobTile->getCells(), blobTile->getSize(), params));
if (decompressedData == NULL)
{
RMInit::logOut << "Error: decompress returned NULL " << blobTile->getOId() << " " << getDomain() << endl;
wrongDecompress = true;
decompressedData = (char*)mymalloc(getSize() * sizeof(char));
memset(decompressedData, 0, getSize());
RMInit::logOut << "Error fixed by returning empty data. ";
if (!AdminIf::isReadOnlyTA())
{
((DBTile*)blobTile.ptr())->setModified();
RMInit::logOut << "Fix was made persistent.";
}
RMInit::logOut << endl;
retval = false;
}
blobTile->setNoModificationData(decompressedData);
blobTile->setNoModificationSize(getSize());
blobTile->setCurrentFormat(r_Array);
}
else {
if (getSize() != blobTile->getSize())
{
RMInit::logOut << "Error: tile with wrong size " << blobTile->getOId() << " " << getDomain() << " is " << blobTile->getSize() << " should be " << getSize() << " format " << blobTile->getDataFormat() << endl;
char* tempPtr = (char*)mymalloc(getSize() * sizeof(char));
memset(tempPtr, '\0', getSize()*sizeof(char));
if(getSize() < blobTile->getSize())
{
memcpy(tempPtr, blobTile->getCells(), getSize());
}
else {
memcpy(tempPtr, blobTile->getCells(), blobTile->getSize());
}
((DBTile*)blobTile.ptr())->setCells(tempPtr);
blobTile->setNoModificationSize(getSize());
RMInit::logOut << "Error fixed by resizing and copying data" << endl;
retval = false;
}
}
return retval;
}
r_Bytes
Tile::calcOffset(const r_Point& point) const
{
int i = 0;
r_Bytes offset = 0;
r_Bytes factor = 1;
// calculate offset
for(i = domain.dimension() - 1; i >= 0; i--)
{
offset += (point[i] - domain[i].low()) * factor;
factor *= domain[i].high() - domain[i].low() + 1;
}
return offset;
}