summaryrefslogtreecommitdiffstats
path: root/indexmgr/mddobjix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'indexmgr/mddobjix.cc')
-rw-r--r--indexmgr/mddobjix.cc529
1 files changed, 529 insertions, 0 deletions
diff --git a/indexmgr/mddobjix.cc b/indexmgr/mddobjix.cc
new file mode 100644
index 0000000..6e85d97
--- /dev/null
+++ b/indexmgr/mddobjix.cc
@@ -0,0 +1,529 @@
+/*
+* 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 <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: mddobjix.cc
+ *
+ * MODULE: indexmgr
+ * CLASS: MDDObjIx
+ *
+ * COMMENTS:
+ * none
+ *
+*/
+static const char rcsid[] = "@(#)mddobjix, MDDObjIx: $Id: mddobjix.cc,v 1.30 2002/07/24 14:33:51 hoefner Exp $";
+
+#include <iostream>
+#include <math.h>
+
+#include "indexmgr/mddobjix.hh"
+#include "raslib/rmdebug.hh"
+#include "tilemgr/tile.hh"
+#include "indexmgr/srptindexlogic.hh"
+#include "indexmgr/sdirindexlogic.hh"
+#include "indexmgr/srcindexlogic.hh"
+#include "indexmgr/transdirix.hh"
+#include "relindexif/hierindex.hh"
+#include "relindexif/dbtcindex.hh"
+#include "relindexif/dbrcindexds.hh"
+#include "keyobject.hh"
+#include "reladminif/lists.h"
+#include "relblobif/tileid.hh"
+
+void
+MDDObjIx::setNewLastAccess(const r_Minterval& newLastAccess, const std::vector<Tile*>* newLastTiles)
+ {
+ lastAccess = newLastAccess;
+ releasePersTiles();
+ lastAccessTiles = *newLastTiles;
+ }
+
+void
+MDDObjIx::setNewLastAccess(const Tile* newLastTile, bool clear)
+ {
+ if (clear)
+ {
+ releasePersTiles();
+ lastAccessTiles.erase(lastAccessTiles.begin(), lastAccessTiles.end());
+ }
+ if (newLastTile)
+ {
+ r_Minterval region = newLastTile->getDomain();
+ lastAccess = region;
+ lastAccessTiles.push_back((Tile*)newLastTile);
+ }
+ }
+
+bool
+MDDObjIx::removeTileFromLastAccesses(const Tile* tileToRemove)
+ {
+ bool found = false;
+ std::vector<Tile*>::iterator iter;
+ for (iter = lastAccessTiles.begin(); iter != lastAccessTiles.end() ; iter++)
+ {
+ if (*iter == tileToRemove)
+ {
+ found = true;
+ lastAccessTiles.erase(iter);
+ break;
+ }
+ }
+ if (found)
+ {
+ r_Minterval emptyInterval;
+ lastAccess = emptyInterval;
+ }
+ return found;
+ }
+
+std::vector< Tile* >*
+MDDObjIx::lastAccessIntersect(const r_Minterval& searchInter) const
+ {
+ std::vector< Tile* >* interResult = 0;
+ if ((lastAccess.dimension() != 0) && (lastAccess.covers(searchInter)))
+ {
+ RMDBGONCE(6, RMDebug::module_indexmgr, "MDDObjIx", "lastAccessIntersect Search in the cache ")
+ interResult = new std::vector< Tile* >();
+ interResult->reserve(10);
+ for (int i = 0; i < lastAccessTiles.size(); i++)
+ {
+ if (lastAccessTiles[i]->getDomain().intersects_with(searchInter))
+ interResult->push_back(lastAccessTiles[i]);
+ }
+ if (interResult->size() == 0)
+ {
+ delete interResult;
+ interResult = NULL;
+ }
+ }
+ return interResult;
+ }
+
+Tile*
+MDDObjIx::lastAccessPointQuery(const r_Point& searchPoint) const
+ {
+ Tile* result = 0;
+
+ if ((lastAccess.dimension() != 0) && (lastAccess.covers(searchPoint)))
+ {
+ for (int i = 0; !result && i < lastAccessTiles.size(); i++)
+ {
+ if (lastAccessTiles[i]->getDomain().covers(searchPoint))
+ {
+ result = lastAccessTiles[i];
+ }
+ }
+ }
+ return (result);
+ }
+
+void
+MDDObjIx::releasePersTiles()
+ {
+ RMDBGENTER(6, RMDebug::module_indexmgr, "MDDObjIx", "releasePersTiles()")
+ if (isPersistent())
+ {
+ Tile* t = NULL;
+ for(int i = 0; i < lastAccessTiles.size(); i++)
+ {
+ t = lastAccessTiles[i];
+ delete t;
+ lastAccessTiles[i] = NULL;
+ }
+ lastAccessTiles.clear();
+ }
+ RMDBGEXIT(6, RMDebug::module_indexmgr, "MDDObjIx", "releasePersTiles()")
+ }
+
+void
+MDDObjIx::printStatus(unsigned int level, std::ostream& stream) const
+ {
+ stream << "MDDObjIx [ last access interval = " << lastAccess << " tile cache size = " << lastAccessTiles.size() << " index structure = ";
+ actualIx->printStatus(level, stream);
+ }
+
+DBObjectId
+MDDObjIx::getDBMDDObjIxId() const
+ {
+ return actualIx;
+ }
+
+r_Minterval
+MDDObjIx::getCurrentDomain() const
+ {
+ return actualIx->getCoveredDomain();
+ }
+
+r_Dimension
+MDDObjIx::getDimension() const
+ {
+ return actualIx->getDimension();
+ }
+
+#ifdef RMANBENCHMARK
+void
+MDDObjIx::initializeTimerPointers()
+ {
+ pointQueryTimer= new RMTimer("DirIx", "pointQuery time ");
+ intersectTimer = new RMTimer("DirIx", "intersect time ");
+ getTilesTimer = new RMTimer("DirIx", "getTiles time ");
+ }
+#endif
+
+MDDObjIx::MDDObjIx(const StorageLayout& sl, const r_Minterval& dim, const BaseType* bt)
+ : cellBaseType(bt),
+ myStorageLayout(sl),
+ actualIx(0),
+ _isPersistent(true)
+ {
+ RMDBGENTER(10, RMDebug::module_indexmgr, "MDDObjIx", "MDDObjIx(storage, " << dim << ", type)")
+ lastAccessTiles.reserve(10);
+ if (bt == NULL)
+ {
+ RMDBGMIDDLE(10, RMDebug::module_indexmgr, "MDDObjIx", "TransIndex")
+ _isPersistent = false;
+ }
+ initializeLogicStructure();
+ if (isPersistent())
+ {
+ r_Range temp;
+ switch(myStorageLayout.getIndexType())
+ {
+ case r_RPlus_Tree_Index:
+ actualIx = (HierIndexDS*)new DBHierIndex(dim.dimension(), false, true);
+ break;
+ case r_Reg_Computed_Index:
+ actualIx = new DBRCIndexDS(dim, SRCIndexLogic::computeNumberOfTiles(myStorageLayout, dim));
+ break;
+ case r_Tile_Container_Index:
+ actualIx = (HierIndexDS*)new DBTCIndex(dim.dimension(), false);
+ break;
+ case r_Directory_Index:
+ actualIx = (HierIndexDS*)new DBHierIndex(dim.dimension(), false, true);
+ break;
+ case r_Auto_Index:
+ default:
+ // should never get here. If Auto_Index, a specific index was
+ RMDBGONCE(0, RMDebug::module_indexmgr, "MDDObjIx", "initializeLogicStructure() Auto_Index or unknown index chosen");
+ throw r_Error(UNKNOWN_INDEX_TYPE);
+ break;
+ }
+ }
+ else {
+ //only dirindex supports transient indexes
+ actualIx = new TransDirIx(dim.dimension());
+ }
+#ifdef RMANBENCHMARK
+ initializeTimerPointers();
+#endif
+ RMDBGEXIT(10, RMDebug::module_indexmgr, "MDDObjIx", "MDDObjIx(storage, " << dim << ", type)")
+ }
+
+MDDObjIx::MDDObjIx(DBObjectId newDBIx, const StorageLayout& sl, const BaseType* bt)
+ : cellBaseType(bt),
+ myStorageLayout(sl),
+ actualIx(newDBIx),
+ _isPersistent(true)
+ {
+ initializeLogicStructure();
+ lastAccessTiles.reserve(10);
+#ifdef RMANBENCHMARK
+ initializeTimerPointers();
+#endif
+ }
+
+void
+MDDObjIx::initializeLogicStructure()
+ {
+ switch(myStorageLayout.getIndexType())
+ {
+ case r_RPlus_Tree_Index:
+ case r_Tile_Container_Index:
+ do_getObjs = SRPTIndexLogic::getObjects;
+ do_insertObj = SRPTIndexLogic::insertObject2;
+ do_pointQuery = SRPTIndexLogic::containPointQuery2;
+ do_removeObj = SRPTIndexLogic::removeObject;
+ do_intersect = SRPTIndexLogic::intersect2;
+ break;
+ case r_Reg_Computed_Index:
+ do_getObjs = SRCIndexLogic::getObjects;
+ do_insertObj = SRCIndexLogic::insertObject;
+ do_pointQuery = SRCIndexLogic::containPointQuery;
+ do_removeObj = SRCIndexLogic::removeObject;
+ do_intersect = SRCIndexLogic::intersect;
+ break;
+ case r_Directory_Index:
+ // chosen before this
+ do_getObjs = SDirIndexLogic::getObjects;
+ do_pointQuery = SDirIndexLogic::containPointQuery;
+ do_removeObj = SDirIndexLogic::removeObject;
+ do_intersect = SDirIndexLogic::intersect;
+ do_insertObj = SDirIndexLogic::insertObject;
+ break;
+ default:
+ case r_Auto_Index:
+ // should never get here. If Auto_Index, a specific index was
+ RMInit::logOut << "MDDObjIx::initializeLogicStructure() illegal index (" << myStorageLayout.getIndexType() << ") chosen!" << endl;
+ throw r_Error(ILLEGAL_INDEX_TYPE);
+ break;
+ }
+ }
+
+
+void
+MDDObjIx::insertTile(const Tile* newTile)
+ {
+ if (isPersistent())
+ {
+ ((Tile*)newTile)->setPersistent();
+ }
+ KeyObject t(newTile);
+ do_insertObj(actualIx, t, myStorageLayout);
+ setNewLastAccess(newTile, false);
+ }
+
+bool
+MDDObjIx::removeTile(const Tile* tileToRemove)
+ {
+ RMDBGENTER(4, RMDebug::module_indexmgr, "MDDObjIx", "removeTile(Tile)")
+ bool found = false;
+ // removes from cache, if it's there
+ removeTileFromLastAccesses(tileToRemove);
+
+ // removes from the index itself
+ KeyObject t(tileToRemove);
+ found = do_removeObj(actualIx, t, myStorageLayout);
+ RMDBGEXIT(4, RMDebug::module_indexmgr, "MDDObjIx", "removeTile(Tile)")
+ return found;
+ }
+
+vector< Tile* >*
+MDDObjIx::intersect(const r_Minterval& searchInter) const
+ {
+ RMDBGENTER(4, RMDebug::module_indexmgr, "MDDObjIx", "intersect(" << searchInter << ")")
+#ifdef RMANBENCHMARK
+ if(RManBenchmark >= 3) intersectTimer->start();
+#endif
+
+ vector< Tile* >* result = lastAccessIntersect(searchInter);
+ if (!result)
+ {
+ KeyObjectVector resultKeys;
+ do_intersect(actualIx, searchInter, resultKeys, myStorageLayout);
+ result = new vector< Tile* >();
+ if (!resultKeys.empty())
+ {
+ unsigned int resSize = resultKeys.size();
+ result->reserve(resSize);
+ Tile* t = NULL;
+ unsigned int i = 0;
+ if (isPersistent())
+ {
+//this checks if there are double tiles in the result
+ RMDBGIF(1, RMDebug::module_indexmgr, "MDDObjIx", \
+ DomainMap t; \
+ DomainMap::iterator it; \
+ for (i = 0; i < resSize; i++) \
+ { \
+ DomainPair p(resultKeys[i].getObject().getOId(), \
+ resultKeys[i].getDomain()); \
+ if ((it = t.find(p.first)) != t.end()) \
+ { \
+ RMDBGMIDDLE(0, RMDebug::module_indexmgr, "MDDObjIx", \
+ "intersect(" << searchInter << \
+ ") received double tile: " << \
+ resultKeys[i]) \
+ for (int i = 0; i < resultKeys.size(); i++) \
+ { \
+ RMInit::dbgOut << resultKeys[i] << endl; \
+ } \
+ throw r_Error(TILE_MULTIPLE_TIMES_RETRIEVED); \
+ } \
+ t.insert(p); \
+ } \
+ );
+ for (i = 0; i < resSize; i++)
+ {
+ RMDBGMIDDLE(4, RMDebug::module_indexmgr, "MDDObjIx", "received entry " << resultKeys[i])
+ result->push_back(new Tile(resultKeys[i].getDomain(), cellBaseType, DBTileId(resultKeys[i].getObject())));
+ }
+ }
+ else {
+ for (i = 0; i < resSize; i++)
+ {
+ result->push_back(resultKeys[i].getTransObject());
+ }
+ }
+ ((MDDObjIx*) this)->setNewLastAccess(searchInter, result);
+ }
+ }
+#ifdef RMANBENCHMARK
+ if(RManBenchmark >= 3) intersectTimer->stop();
+#endif
+ RMDBGEXIT(4, RMDebug::module_indexmgr, "MDDObjIx", "intersect(" << searchInter << ") " << (void*)result)
+ return result;
+ }
+
+char*
+MDDObjIx::pointQuery(const r_Point& searchPoint)
+ {
+ char* result = 0;
+
+ Tile* resultTile = containPointQuery(searchPoint);
+
+ if(resultTile)
+ {
+ result = resultTile->getCell(searchPoint);
+ }
+ return result;
+ }
+
+const char*
+MDDObjIx::pointQuery(const r_Point& searchPoint) const
+ {
+ const char* result = 0;
+
+ Tile* resultTile = containPointQuery(searchPoint);
+
+ if(resultTile)
+ {
+ result = resultTile->getCell(searchPoint);
+ }
+ return result;
+ }
+
+Tile*
+MDDObjIx::containPointQuery(const r_Point& searchPoint) const
+ {
+
+ Tile* resultTile = 0;
+
+#ifdef RMANBENCHMARK
+ if(RManBenchmark >= 4) pointQueryTimer->start();
+#endif
+ resultTile = lastAccessPointQuery(searchPoint);
+ if (!resultTile)
+ {
+ KeyObject resultKey;
+ do_pointQuery(actualIx, searchPoint, resultKey, myStorageLayout);
+ if (resultKey.isInitialised())
+ {
+ if (isPersistent())
+ {
+ resultTile = new Tile(resultKey.getDomain(), cellBaseType, DBTileId(resultKey.getObject()));
+ // for rcindex
+ ((DBObject*)resultKey.getObject().ptr())->setCached(false);
+ }
+ else {
+ resultTile = resultKey.getTransObject();
+ }
+ ((MDDObjIx*) this)->setNewLastAccess(resultTile);
+ }
+ }
+
+#ifdef RMANBENCHMARK
+ if (RManBenchmark >= 4) pointQueryTimer->stop();
+#endif
+ return resultTile;
+ }
+
+vector< Tile* >*
+MDDObjIx::getTiles() const
+ {
+#ifdef RMANBENCHMARK
+ if(RManBenchmark >= 3) getTilesTimer->start();
+#endif
+ vector< Tile* >* result = NULL;
+ KeyObjectVector resultKeys;
+ do_getObjs(actualIx, resultKeys, myStorageLayout);
+ if (!resultKeys.empty())
+ {
+ result = new vector< Tile* >();
+ unsigned int resSize = resultKeys.size();
+ result->reserve(resSize);
+ Tile* t = 0;
+ if (isPersistent())
+ {
+//this checks if there are double tiles in the result
+ RMDBGIF(1, RMDebug::module_indexmgr, "MDDObjIx", \
+ DomainMap tmap; \
+ DomainMap::iterator it; \
+ for (int cnt = 0; cnt < resSize; cnt++) \
+ { \
+ DomainPair p(resultKeys[cnt].getObject().getOId(), \
+ resultKeys[cnt].getDomain()); \
+ if ((it = tmap.find(p.first)) != tmap.end()) \
+ { \
+ RMDBGMIDDLE(0, RMDebug::module_indexmgr, "MDDObjIx", \
+ "getTiles() received double tile: " << \
+ resultKeys[cnt]) \
+ for (int cnt = 0; cnt < resultKeys.size(); cnt++) \
+ { \
+ RMInit::dbgOut << resultKeys[cnt] << endl; \
+ } \
+ throw r_Error(TILE_MULTIPLE_TIMES_RETRIEVED ); \
+ } \
+ tmap.insert(p); \
+ } \
+ );
+ for (int i = 0; i < resSize; i++)
+ {
+ result->push_back(new Tile(resultKeys[i].getDomain(), cellBaseType, DBTileId(resultKeys[i].getObject())));
+ }
+ }
+ else {
+ for (int i = 0; i < resultKeys.size(); i++)
+ {
+ result->push_back(resultKeys[i].getTransObject());
+ }
+ }
+ r_Minterval emptyInterval;
+ ((MDDObjIx*) this)->setNewLastAccess(emptyInterval, result);
+ }
+#ifdef RMANBENCHMARK
+ if(RManBenchmark >= 3) getTilesTimer->stop();
+#endif
+ return result;
+ }
+
+
+bool
+MDDObjIx::isPersistent() const
+ {
+ return _isPersistent;
+ }
+
+MDDObjIx::~MDDObjIx()
+ {
+ releasePersTiles();
+ actualIx->destroy();
+ actualIx = 0;
+
+#ifdef RMANBENCHMARK
+ pointQueryTimer->setOutput(0);
+ if (pointQueryTimer) delete pointQueryTimer;
+ intersectTimer->setOutput(0);
+ if (intersectTimer) delete intersectTimer;
+ getTilesTimer->setOutput(0);
+ if (getTilesTimer) delete getTilesTimer;
+#endif
+ }