/* * 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 . */ #include #include "dbtcindex.hh" #include "raslib/rmdebug.hh" #include "reladminif/lists.h" #include "reladminif/sqlerror.hh" #include "reladminif/externs.h" #include "relblobif/blobtile.hh" #include "relblobif/inlinetile.hh" #include "relblobif/tileid.hh" #include "reladminif/objectbroker.hh" #include "reladminif/adminif.hh" #include "reladminif/dbref.hh" #include "storagemgr/sstoragelayout.hh" #include "indexmgr/keyobject.hh" void DBTCIndex::setMappingHasChanged() { mappingHasChanged = true; } void DBTCIndex::setInlineTileHasChanged() { inlineTileHasChanged = true; } DBTCIndex::DBTCIndex(const OId& id) : DBHierIndex(id), _isLoaded(false), inlineTileHasChanged(false), mappingHasChanged(false), hasBlob(false) { RMDBGENTER(7, RMDebug::module_indexif, "DBTCIndex", "DBTCIndex(" << myOId << ")"); throw r_Error(r_Error::r_Error_FeatureNotSupported); readFromDb(); _isLoaded = !hasBlob; RMDBGEXIT(7, RMDebug::module_indexif, "DBTCIndex", "DBTCIndex(" << myOId << ")"); } IndexDS* DBTCIndex::getNewInstance() const { return (HierIndexDS*)new DBTCIndex(getDimension(), !isLeaf()); } DBTCIndex::DBTCIndex(r_Dimension dim, bool isNode) : DBHierIndex(dim, isNode, false), _isLoaded(true), inlineTileHasChanged(false), mappingHasChanged(false), hasBlob(false) { RMDBGENTER(7, RMDebug::module_indexif, "DBTCIndex", "DBTCIndex(" << dim << ", " << (int)_isLoaded << ") " << myOId); throw r_Error(r_Error::r_Error_FeatureNotSupported); objecttype = OId::DBTCINDEXOID; setPersistent(true); setCached(true); RMDBGEXIT(7, RMDebug::module_indexif, "DBTCIndex", "DBTCIndex(" << dim << ") " << myOId); } void DBTCIndex::printStatus(unsigned int level, std::ostream& stream) const { char* indent = new char[level*2 +1]; for (unsigned int j = 0; j < level*2 ; j++) indent[j] = ' '; indent[level*2] = '\0'; stream << indent << "DBTCIndex "; DBHierIndex::printStatus(level + 1, stream); delete[] indent; } DBTCIndex::~DBTCIndex() { RMDBGENTER(7, RMDebug::module_indexif, "DBTCIndex", "~DBTCIndex() " << myOId); if (!isModified()) { if (!AdminIf::isReadOnlyTA()) { if (isLeaf()) decideForInlining(); if (mappingHasChanged) updateTileIndexMappings(); if (inlineTileHasChanged) { storeTiles(); changeBOIdToIOId(); } if (isModified()) DBHierIndex::updateInDb(); if (isLeaf()) changeIOIdToBOId(); } } else validate(); currentDbRows = 0; parent = OId(0); RMDBGEXIT(7, RMDebug::module_indexif, "DBTCIndex", "~DBTCIndex() " << myOId); } void DBTCIndex::registerIOIds() { RMDBGENTER(7, RMDebug::module_indexif, "DBTCIndex", "registerIOIds() " << myOId); for (KeyObjectVector::iterator i = myKeyObjects.begin(); i != myKeyObjects.end(); i++) if ((*i).getObject().getOId().getType() == OId::INNEROID) { RMDBGMIDDLE(7, RMDebug::module_indexif, "DBTCIndex", "registering tileoid " << OId((*i).getObject().getOId().getCounter(), OId::INLINETILEOID) << " indexoid " << myOId); ObjectBroker::registerTileIndexMapping(OId((*i).getObject().getOId().getCounter(), OId::INLINETILEOID), myOId); hasBlob = true; } RMDBGEXIT(7, RMDebug::module_indexif, "DBTCIndex", "registerIOIds() " << myOId); } void DBTCIndex::changeIOIdToBOId() { for (KeyObjectVector::iterator it = myKeyObjects.begin(); it != myKeyObjects.end(); it++) if ((*it).getObject().getOId().getType() == OId::INNEROID) { OId o((*it).getObject().getOId().getCounter(), OId::INLINETILEOID); DBObjectPPair p(o, 0); inlineTiles.insert(p); (*it).setObject(o); } } void DBTCIndex::changeBOIdToIOId() { for (KeyObjectVector::iterator it = myKeyObjects.begin(); it != myKeyObjects.end(); it++) { DBObjectPMap::iterator itit = inlineTiles.find((*it).getObject().getOId()); if (itit != inlineTiles.end()) { (*it).setObject(OId((*it).getObject().getOId().getCounter(), OId::INNEROID)); } } } void DBTCIndex::removeInlineTile(InlineTile* it) { DBObjectPMap::iterator itit = inlineTiles.find(it->getOId()); if (itit != inlineTiles.end()) { inlineTiles.erase(itit); setMappingHasChanged(); setInlineTileHasChanged(); ObjectBroker::deregisterTileIndexMapping(it->getOId(), myOId); } else { RMDBGONCE(0, RMDebug::module_indexif, "DBTCIndex", "deregisterInlineTile(" << it->getOId() << ") it not found") } } void DBTCIndex::addInlineTile(InlineTile* it) { if (!_isLoaded) readInlineTiles(); DBObjectPPair p(it->getOId(), it); inlineTiles.insert(p); ObjectBroker::registerTileIndexMapping(it->getOId(), myOId); setMappingHasChanged(); setInlineTileHasChanged(); } void DBTCIndex::insertInDb() throw (r_Error) { RMDBGENTER(5, RMDebug::module_indexif, "DBTCIndex", "insertInDb() " << myOId); if (isLeaf()) { decideForInlining(); if (inlineTileHasChanged || mappingHasChanged) { updateTileIndexMappings(); insertBlob(); storeTiles(); changeBOIdToIOId(); } } DBHierIndex::insertInDb(); if (isLeaf()) changeIOIdToBOId(); RMDBGEXIT(5, RMDebug::module_indexif, "DBTCIndex", "insertInDb() " << myOId); } void DBTCIndex::readFromDb() throw (r_Error) { RMDBGENTER(5, RMDebug::module_indexif, "DBTCIndex", "readFromDb() " << myOId); DBHierIndex::readFromDb(); if (isLeaf()) { registerIOIds(); changeIOIdToBOId(); } inlineTileHasChanged = false; mappingHasChanged = false; RMDBGEXIT(5, RMDebug::module_indexif, "DBTCIndex", "readFromDb() " << myOId); } void DBTCIndex::updateInDb() throw (r_Error) { RMDBGENTER(5, RMDebug::module_indexif, "DBTCIndex", "updateInDb() " << myOId); if (isLeaf()) decideForInlining(); if (mappingHasChanged) updateTileIndexMappings(); if (inlineTileHasChanged) storeTiles(); if (inlineTiles.size() != 0) changeBOIdToIOId(); DBHierIndex::updateInDb(); if (isLeaf()) changeIOIdToBOId(); RMDBGEXIT(5, RMDebug::module_indexif, "DBTCIndex", "updateInDb() " << myOId); } InlineTile* DBTCIndex::getInlineTile(const OId& itid) { InlineTile* retval = 0; DBObjectPMap::iterator itit; if (!_isLoaded) { readInlineTiles(); } itit = inlineTiles.find(itid); if (itit != inlineTiles.end()) { retval = (InlineTile*)(*itit).second; } return retval; } void DBTCIndex::readyForRemoval(const OId& id) { if (id.getType() == OId::INLINETILEOID) { DBObjectPMap::iterator itit; itit = inlineTiles.find(id); if (inlineTiles.end() != itit) { if (!_isLoaded) { readInlineTiles(); itit = inlineTiles.find(id); ((*itit).second)->setCached(false); ((InlineTile*)(*itit).second)->outlineTile(); } else { ((*itit).second)->setCached(false); ((InlineTile*)(*itit).second)->outlineTile(); } } } } bool DBTCIndex::removeObject(const KeyObject& entry) { RMDBGENTER(4, RMDebug::module_indexif, "DBTCIndex", "removeObject(" << entry << ") " << myOId); if (isLeaf()) readyForRemoval(entry.getObject().getOId()); bool found = DBHierIndex::removeObject(entry); RMDBGEXIT(4, RMDebug::module_indexif, "DBTCIndex", "removeEntry(" << entry << ") " << myOId << " " << found); return found; } bool DBTCIndex::removeObject(unsigned int pos) { RMDBGENTER(4, RMDebug::module_indexif, "DBTCIndex", "removeObject(" << pos << ") " << myOId); if (isLeaf()) if (pos <= myKeyObjects.size()) readyForRemoval(myKeyObjects[pos].getObject().getOId()); bool found = DBHierIndex::removeObject((unsigned int)pos); RMDBGEXIT(4, RMDebug::module_indexif, "DBTCIndex", "removeEntry(" << pos << ") " << myOId << " " << found); return found; } void DBTCIndex::decideForInlining() { RMDBGENTER(5, RMDebug::module_indexif, "DBTCIndex", "decideForInlining() " << myOId); if (isLeaf()) { InlineTile* itile = NULL; KeyObjectVector::iterator it; for (it = myKeyObjects.begin(); it != myKeyObjects.end(); it++) { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", " we do oid " << (*it)); if ((*it).getObject().getOId().getType() == OId::INLINETILEOID) if ((itile = (InlineTile*)ObjectBroker::isInMemory((*it).getObject().getOId())) != 0) { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", "in memory"); //decide for inlineing if (itile->isInlined()) { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", "inlined"); if (itile->getSize() > StorageLayout::DefaultPCTMax) { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", "needs to be outlined"); itile->outlineTile(); } } else { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", "outlined"); if (itile->getSize() < StorageLayout::DefaultMinimalTileSize) { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", "needs to be inlined"); itile->inlineTile(myOId); } } } else { RMDBGMIDDLE(5, RMDebug::module_indexif, "DBTCIndex", "not in memory"); } } } RMDBGEXIT(5, RMDebug::module_indexif, "DBTCIndex", "decideForInlining() " << myOId); }