From 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Fri, 24 Apr 2009 07:20:22 -0400 Subject: Initial commit --- mddmgr/mddobj.cc | 392 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 mddmgr/mddobj.cc (limited to 'mddmgr/mddobj.cc') diff --git a/mddmgr/mddobj.cc b/mddmgr/mddobj.cc new file mode 100644 index 0000000..59cc4aa --- /dev/null +++ b/mddmgr/mddobj.cc @@ -0,0 +1,392 @@ +/* +* 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 . +/ +/** + * SOURCE: persmddobj.cc + * + * MODULE: cachetamgr + * CLASS: MDDObj + * + * COMMENTS: + * none + * +*/ + +#include "mymalloc/mymalloc.h" + +static const char rcsid[] = "@(#)persmddobj, PersMDDObj: $Id: mddobj.cc,v 1.26 2005/07/06 22:43:20 rasdev Exp $"; + +#include +#include +#include + +#include "mddobj.hh" +#include "relmddif/dbmddobj.hh" +#include "relindexif/indexid.hh" +#include "reladminif/eoid.hh" + +#include "tilemgr/tile.hh" +#include "relcatalogif/mdddomaintype.hh" +#include "raslib/mddtypes.hh" +#include "raslib/rmdebug.hh" +#include "indexmgr/mddobjix.hh" + +const r_Minterval& +MDDObj::checkStorage(const r_Minterval& domain2) throw (r_Error) + { + r_Minterval domain(domain2.dimension()); + if (myStorageLayout->getIndexType() == r_Reg_Computed_Index) + { + if (myStorageLayout->getTilingScheme() != r_RegularTiling) + { + RMInit::logOut << "MDDObj::checkStorage(" << domain2 << ") the rc index needs a regular tiling defined" << endl; + throw r_Error(RCINDEXWITHOUTREGULARTILING); + } + r_Dimension dim = domain2.dimension(); + // make sure the tileConfig is fixed + r_Minterval tileConfig = myStorageLayout->getTileConfiguration(); + myStorageLayout->setTileConfiguration(tileConfig); + r_Point mddDomainExtent = domain2.get_extent(); + r_Point tileConfigExtent = tileConfig.get_extent(); + for (r_Dimension i = 0; i < dim; i++) + { + if (!domain2[i].is_high_fixed() || !domain2[i].is_low_fixed() || !tileConfig[i].is_high_fixed() || !tileConfig[i].is_low_fixed()) + { + RMInit::logOut << "MDDObj::checkStorage(" << domain2 << ") the rc index needs a domain and tile configuration with fixed domains in all dimensions. Dimension " << i << " seems not to be fixed." << endl; + throw r_Error(RCINDEXWITHINCOMPATIBLEMARRAYTYPE); + } + if (mddDomainExtent[i]%tileConfigExtent[i] != 0) + { + RMInit::logOut << "MDDObj::checkStorage(" << domain2 << ") the tile configuration (" << tileConfig << ") does not fit the domain of the marray (" << domain << ")." << endl; + throw r_Error(TILECONFIGMARRAYINCOMPATIBLE); + } + } + } + return domain2; + } + +MDDObj::MDDObj(const MDDBaseType* mddType, const r_Minterval& domain) + : myMDDIndex(NULL), + myDBMDDObj(), + myStorageLayout(NULL) + { + if (!mddType) + { + RMInit::logOut << "MDD type is NULL. Please report query or raslib program to Customer Support." << endl; + throw r_Error(MDDTYPE_NULL); + } + + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << mddType->getName() << ", " << domain << ") " << (r_Ptr)this); + myStorageLayout = new StorageLayout(r_Directory_Index); + myMDDIndex = new MDDObjIx(*myStorageLayout, domain); + myDBMDDObj = new DBMDDObj(mddType, domain, myMDDIndex->getDBMDDObjIxId(), myStorageLayout->getDBStorageLayout()); + } + +MDDObj::MDDObj(const MDDBaseType* mddType, const r_Minterval& domain, const OId& newOId, const StorageLayout& ms) throw (r_Error) + : myMDDIndex(NULL), + myDBMDDObj(), + myStorageLayout(NULL) + { + if (!mddType) + { + RMInit::logOut << "MDD type is NULL. Please report query or raslib program to Customer Support." << endl; + throw r_Error(MDDTYPE_NULL); + } + + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << mddType->getName() << ", " << domain << ", " << newOId << ", " << ms.getDBStorageLayout().getOId() << ") " << (r_Ptr)this); + myStorageLayout = new StorageLayout(ms); + myMDDIndex = new MDDObjIx(*myStorageLayout, checkStorage(domain), mddType->getBaseType()); + myDBMDDObj = new DBMDDObj(mddType, domain, myMDDIndex->getDBMDDObjIxId(), ms.getDBStorageLayout(), newOId); + } + +MDDObj::MDDObj(const DBMDDObjId& dbmddobj) throw(r_Error) + : myMDDIndex(NULL), + myDBMDDObj(dbmddobj), + myStorageLayout(NULL) + { + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(DBRef " << dbmddobj.getOId() << ") " << (r_Ptr)this); + myStorageLayout = new StorageLayout(myDBMDDObj->getDBStorageLayout()); + myMDDIndex = new MDDObjIx(myDBMDDObj->getDBIndexDS(), *myStorageLayout, myDBMDDObj->getMDDBaseType()->getBaseType()); + } + +MDDObj::MDDObj(const OId& givenOId) throw(r_Error) + : myMDDIndex(NULL), + myDBMDDObj(OId()), + myStorageLayout(NULL) + { + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << givenOId << ") " << (r_Ptr)this); + myDBMDDObj = DBMDDObjId(givenOId); + myStorageLayout = new StorageLayout(myDBMDDObj->getDBStorageLayout()); + myMDDIndex = new MDDObjIx(myDBMDDObj->getDBIndexDS(), *myStorageLayout, myDBMDDObj->getMDDBaseType()->getBaseType()); + } + +MDDObj::MDDObj(const MDDBaseType* mddType, const r_Minterval& domain, const StorageLayout& ms) + : myMDDIndex(NULL), + myDBMDDObj(OId()), + myStorageLayout(NULL) + { + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "MDDObj(" << mddType->getName() << ", " << domain << ", " << ms.getDBStorageLayout().getOId() << ") " <<(r_Ptr)this); + if (!mddType) + { + RMInit::logOut << "MDD type is NULL. Please report query or raslib program to Customer Support." << endl; + throw r_Error(MDDTYPE_NULL); + } + myStorageLayout = new StorageLayout(ms); + myMDDIndex = new MDDObjIx(*myStorageLayout, checkStorage(domain), mddType->getBaseType()); + myDBMDDObj = new DBMDDObj(mddType, domain, myMDDIndex->getDBMDDObjIxId(), ms.getDBStorageLayout()); + myDBMDDObj->setPersistent(); + } + + +/* +insert tile: + tiles may have to be retiled. + the storage layout returns the domains into which the tile should be divided before insertion. + if there is not enough data to fill a complete layout domain, then 0 will be set. +*/ +void +MDDObj::insertTile(Tile* newTile) + { + RMDBGENTER(2, RMDebug::module_mddmgr, "MDDObj", "insertTile(Tile " << newTile->getDomain() << ")") + std::vector layoutDoms = myStorageLayout->getLayout(newTile->getDomain()); +RMDBGIF(10, RMDebug::module_mddmgr, "printlayoutdoms", \ + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "storage layout returned the following domains") \ + for (std::vector ::iterator domit = layoutDoms.begin(); domit != layoutDoms.end(); domit++) \ + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", *domit) \ + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "end of storage layout domains")) + + Tile* tile = NULL; + Tile* tile2 = NULL; + r_Area tempArea = 0; + r_Area completeArea = 0; + r_Minterval tempDom; + r_Minterval tileDom = newTile->getDomain(); + std::vector* indexTiles = NULL; + char* newContents = NULL; + size_t sizeOfData = 0; + bool checkEquality = true; + for (std::vector::iterator it = layoutDoms.begin(); it != layoutDoms.end(); it++) + { + if (checkEquality && tileDom == *it) + {// normal case. just insert the tile. + // this case also means that there was no insertion in the previous loops + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "tile domain is same as layout domain, just inserting data") + myMDDIndex->insertTile((Tile*)newTile); + // set to NULL so it will not get deleted at the end of the method + newTile = NULL; + if (layoutDoms.size() != 1) + { + RMInit::logOut << "MDDObj::insertTile(Tile " << tileDom << ") the layout has more than one element but the tile domain completely covers the layout domain" << endl; + throw r_Error(LAYOUTALGORITHMPROBLEM); + } + } + else {// we need to check if there is already a tile defined here + // this could have been created in a previous loop run + // we are using retiling here. *it is therefore an indivisible layout domain. + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "tile domain (" << tileDom << ") is not the same as layout domain (" << *it << ")") + indexTiles = myMDDIndex->intersect(*it); + if (indexTiles) + {// there was a tile in the run before, which overlapped with this layout domain + // there may only be one entry in the index for this domain. + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "found tiles (" << indexTiles->size() << ") in layout domain " << *it) + if (indexTiles->size() != 1) + { + RMInit::logOut << "MDDObj::insertTile(Tile " << tileDom << ") the index contains many entries for one layout domain" << endl; + throw r_Error(LAYOUTALGORITHMPROBLEM); + } + // update the existing tile with the new data + tempDom = (*it).create_intersection(tileDom); + (*(indexTiles->begin()))->copyTile(tempDom, newTile, tempDom); + //RMInit::dbgOut << "updated tile to" << endl; + // (*(indexTiles->begin()))->printStatus(99,RMInit::dbgOut); + } + else {// there was no tile overlapping the current layout domain yet + // create a new tile covering the whole layout domain + // must be computed everytime because layoutDoms may change in size + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "found no tiles in layout domain " << *it) + // generate a tile of the domain : layout domain + completeArea = (*it).cell_count(); + sizeOfData = sizeof(char) * completeArea * getMDDBaseType()->getBaseType()->getSize(); + newContents = (char*)mymalloc(sizeOfData); + // initialise to 0 + memset(newContents, 0, sizeOfData); + tile = new Tile(*it, getMDDBaseType()->getBaseType(), newContents, 0, newTile->getDataFormat()); + tile->setParameters(newTile->getParameters()); + tempDom = (*it).create_intersection(tileDom); + // only update the actual data - the rest was set to 0 + tile->copyTile(tempDom, newTile, tempDom); + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "created tile with domain " << tile->getDomain()) + //RMInit::dbgOut << "insert tile" << endl; + // tile->printStatus(99,RMInit::dbgOut); + //FIXME: should not be neccessary + tile->compress(); + myMDDIndex->insertTile((Tile*)tile); + } + } + checkEquality = false; + } + if (newTile) + { + RMDBGMIDDLE(2, RMDebug::module_mddmgr, "MDDObj", "have to delete newTile") + if (newTile->isPersistent()) + ((Tile*)newTile)->getDBTile()->setPersistent(false); + delete newTile; + } + RMDBGEXIT(2, RMDebug::module_mddmgr, "MDDObj", "insertTile(Tile)") + } + +std::vector< Tile* >* +MDDObj::intersect(const r_Minterval& searchInter) const + { + std::vector* retval = myMDDIndex->intersect(searchInter); +RMDBGIF(10, RMDebug::module_mddmgr, "printtiles", \ + if (retval) \ + { \ + int t = RManDebug; \ + RManDebug = 0; \ + for (std::vector::iterator it = retval->begin(); it != retval->end();it++) \ + { \ + RMInit::dbgOut << "FOUND " << (*it)->getDomain() << " " << endl; \ + (*it)->printStatus(0, RMInit::dbgOut); \ + } \ + RManDebug = t; \ + }) + return retval; + } + +std::vector< Tile* >* +MDDObj::getTiles() const + { + return myMDDIndex->getTiles(); + } + +char* +MDDObj::pointQuery(const r_Point& searchPoint) + { + return myMDDIndex->pointQuery(searchPoint); + } + +const char* +MDDObj::pointQuery(const r_Point& searchPoint) const + { + return myMDDIndex->pointQuery(searchPoint); + } + +DBMDDObjId +MDDObj::getDBMDDObjId() const + { + return myDBMDDObj; + } + +const MDDBaseType* +MDDObj::getMDDBaseType() const + { + return myDBMDDObj->getMDDBaseType(); + } + +r_Minterval +MDDObj::getDefinitionDomain() const + { + return myDBMDDObj->getDefinitionDomain(); + } + +r_Minterval +MDDObj::getCurrentDomain() const + { + return myMDDIndex->getCurrentDomain(); + } + +const char* +MDDObj::getCellTypeName() const + { + return myDBMDDObj->getCellTypeName(); + } + +const BaseType* +MDDObj::getCellType() const + { + return myDBMDDObj->getCellType(); + } + +r_Dimension +MDDObj::getDimension() const + { + return myDBMDDObj->dimensionality(); + } + +bool +MDDObj::isPersistent() const + { + return myDBMDDObj->isPersistent(); + } + + +int +MDDObj::getOId(OId* pOId) const + { + *pOId = myDBMDDObj->getOId(); + return (pOId->getCounter() == 0); + } + +int +MDDObj::getEOId(EOId* pEOId) const + { + *pEOId = myDBMDDObj->getEOId(); + return (pEOId->getCounter() == 0); + } + +void +MDDObj::printStatus(unsigned int level, std::ostream& stream) const + { + myDBMDDObj->printStatus(level, stream); + myMDDIndex->printStatus(level, stream); + } + +void +MDDObj::removeTile(Tile*& tileToRemove) + { + int found = myMDDIndex->removeTile(tileToRemove); + if (found) + { + // frees its memory. Persistent freeing?? + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "removeTile() about to delete tile") + ((Tile*) tileToRemove)->getDBTile().delete_object(); + delete tileToRemove; + tileToRemove = 0; + } + } + +MDDObj::~MDDObj() + { + RMDBGONCE(2, RMDebug::module_mddmgr, "MDDObj", "~MDDObj() " << (r_Ptr)this) + + delete myMDDIndex; + myMDDIndex = NULL; + delete myStorageLayout; + myStorageLayout = NULL; + } + +void +MDDObj::releaseTiles() + { + myMDDIndex->releasePersTiles(); + } -- cgit