summaryrefslogtreecommitdiff
path: root/cpp/src/Freeze/SharedDb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Freeze/SharedDb.cpp')
-rw-r--r--cpp/src/Freeze/SharedDb.cpp720
1 files changed, 0 insertions, 720 deletions
diff --git a/cpp/src/Freeze/SharedDb.cpp b/cpp/src/Freeze/SharedDb.cpp
deleted file mode 100644
index ab651e267c2..00000000000
--- a/cpp/src/Freeze/SharedDb.cpp
+++ /dev/null
@@ -1,720 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#include <Freeze/SharedDb.h>
-#include <IceUtil/StaticMutex.h>
-#include <Freeze/Exception.h>
-#include <Freeze/Util.h>
-#include <Freeze/Catalog.h>
-#include <Freeze/CatalogIndexList.h>
-#include <algorithm>
-
-using namespace std;
-using namespace IceUtil;
-using namespace Ice;
-using namespace Freeze;
-
-namespace
-{
-
-StaticMutex _mapMutex = ICE_STATIC_MUTEX_INITIALIZER;
-StaticMutex _refCountMutex = ICE_STATIC_MUTEX_INITIALIZER;
-
-const string _catalogName = "__catalog";
-const string _catalogIndexListName = "__catalogIndexList";
-
-inline void
-checkTypes(const SharedDb& sharedDb, const string& key, const string& value)
-{
- if(key != sharedDb.key())
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = sharedDb.dbName() + "'s key type is " + sharedDb.key() + ", not " + key;
- throw ex;
- }
- if(value != sharedDb.value())
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = sharedDb.dbName() + "'s value type is " + sharedDb.value() + ", not " + value;
- throw ex;
- }
-}
-}
-
-extern "C"
-{
-static int customCompare(DB* db, const DBT* dbt1, const DBT* dbt2)
-{
- SharedDb* me = static_cast<SharedDb*>(db->app_private);
- Ice::Byte* first = static_cast<Ice::Byte*>(dbt1->data);
- Key k1(first, first + dbt1->size);
- first = static_cast<Ice::Byte*>(dbt2->data);
- Key k2(first, first + dbt2->size);
-
- return me->getKeyCompare()->compare(k1, k2);
-}
-}
-
-Freeze::SharedDb::SharedDbMap* Freeze::SharedDb::sharedDbMap = 0;
-
-const string&
-Freeze::catalogName()
-{
- return _catalogName;
-}
-
-const string&
-Freeze::catalogIndexListName()
-{
- return _catalogIndexListName;
-}
-
-SharedDbPtr
-Freeze::SharedDb::get(const ConnectionIPtr& connection,
- const string& dbName,
- const string& key,
- const string& value,
- const KeyCompareBasePtr& keyCompare,
- const vector<MapIndexBasePtr>& indices,
- bool createDb)
-{
- if(dbName == _catalogName)
- {
- //
- // We don't want to lock the _mapMutex to retrieve the catalog
- //
-
- SharedDbPtr result = connection->dbEnv()->getCatalog();
- checkTypes(*result, key, value);
- return result;
- }
- else if(dbName == _catalogIndexListName)
- {
- SharedDbPtr result = connection->dbEnv()->getCatalogIndexList();
- checkTypes(*result, key, value);
- return result;
- }
-
- StaticMutex::Lock lock(_mapMutex);
-
- if(sharedDbMap == 0)
- {
- sharedDbMap = new SharedDbMap;
- }
-
- MapKey mapKey;
- mapKey.envName = connection->envName();
- mapKey.communicator = connection->communicator();
- mapKey.dbName = dbName;
-
- {
- SharedDbMap::iterator p = sharedDbMap->find(mapKey);
- if(p != sharedDbMap->end())
- {
- checkTypes(*(p->second), key, value);
- p->second->connectIndices(indices);
- return p->second;
- }
- }
-
- //
- // MapKey not found, let's create and open a new Db
- //
-
- //
- // Since we're going to put this SharedDb in the map no matter
- // what, we use our own transaction and connection to do so
- //
-
- ConnectionIPtr insertConnection = new ConnectionI(SharedDbEnv::get(mapKey.communicator, mapKey.envName));
-
-
- auto_ptr<SharedDb> result(new SharedDb(mapKey, key, value, insertConnection,
- keyCompare, indices, createDb));
-
- //
- // Insert it into the map
- //
- pair<SharedDbMap::iterator, bool> insertResult;
- insertResult= sharedDbMap->insert(SharedDbMap::value_type(mapKey, result.get()));
- assert(insertResult.second);
- result->_inMap = true;
-
- return result.release();
-}
-
-SharedDbPtr
-Freeze::SharedDb::create(const ConnectionIPtr& connection,
- const string& dbName,
- const string& key,
- const string& value,
- const KeyCompareBasePtr& keyCompare,
- const vector<MapIndexBasePtr>& indices)
-{
- MapKey mapKey;
- mapKey.envName = connection->envName();
- mapKey.communicator = connection->communicator();
- mapKey.dbName = dbName;
-
- return new SharedDb(mapKey, key, value, connection, keyCompare, indices, true);
-}
-
-void
-Freeze::SharedDb::openCatalogs(SharedDbEnv& dbEnv, SharedDbPtr& catalog, SharedDbPtr& catalogIndexList)
-{
- StaticMutex::Lock lock(_mapMutex);
-
- if(sharedDbMap == 0)
- {
- sharedDbMap = new SharedDbMap;
- }
-
- MapKey mapKey;
- mapKey.envName = dbEnv.getEnvName();
- mapKey.communicator = dbEnv.getCommunicator();
- mapKey.dbName = _catalogName;
-
-
- auto_ptr<SharedDb> newCatalog(new SharedDb(mapKey, CatalogKeyCodec::typeId(),
- CatalogValueCodec::typeId(), dbEnv.getEnv()));
-
- //
- // Insert it into the map
- //
- pair<SharedDbMap::iterator, bool> insertResult
- = sharedDbMap->insert(SharedDbMap::value_type(mapKey, newCatalog.get()));
-
- if(!insertResult.second)
- {
- //
- // That's very wrong
- //
- assert(0);
- throw DatabaseException(__FILE__, __LINE__, "Catalog already opened");
- }
- newCatalog->_inMap = true;
-
- mapKey.dbName = _catalogIndexListName;
-
- auto_ptr<SharedDb> newCatalogIndexList(new SharedDb(mapKey, CatalogIndexListKeyCodec::typeId(),
- CatalogIndexListValueCodec::typeId(), dbEnv.getEnv()));
-
- insertResult
- = sharedDbMap->insert(SharedDbMap::value_type(mapKey, newCatalogIndexList.get()));
-
- if(!insertResult.second)
- {
- assert(0);
- throw DatabaseException(__FILE__, __LINE__, "CatalogIndexList already opened");
- }
- newCatalogIndexList->_inMap = true;
-
-
- catalog = newCatalog.release();
- catalogIndexList = newCatalogIndexList.release();
-}
-
-
-Freeze::SharedDb::~SharedDb()
-{
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "closing Db \"" << _mapKey.dbName << "\"";
- }
-
- cleanup(false);
-}
-
-void Freeze::SharedDb::__incRef()
-{
- if(_trace >= 2)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "incrementing reference count for Db \"" << _mapKey.dbName << "\"";
- }
-
- IceUtil::StaticMutex::Lock lock(_refCountMutex);
- _refCount++;
-}
-
-void Freeze::SharedDb::__decRef()
-{
- if(_trace >= 2)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "removing reference count for Db \"" << _mapKey.dbName << "\"";
- }
-
- IceUtil::StaticMutex::Lock lock(_refCountMutex);
- if(--_refCount == 0)
- {
- IceUtil::StaticMutex::TryLock mapLock(_mapMutex);
- if(!mapLock.acquired())
- {
- MapKey mapKey = _mapKey;
-
- //
- // Reacquire mutex in proper order
- //
- lock.release();
- mapLock.acquire();
- lock.acquire();
-
- if(_inMap)
- {
- //
- // Now, maybe another thread has deleted 'this'; let's check
- // we're still in the map
- //
- if(sharedDbMap == 0)
- {
- return;
- }
-
- SharedDbMap::iterator p = sharedDbMap->find(mapKey);
-
- if(p == sharedDbMap->end() || p->second != this)
- {
- //
- // 'this' has been deleted by another thread
- //
- return;
- }
- }
-
- if(_refCount > 0)
- {
- return;
- }
- }
-
- if(_inMap)
- {
- //
- // Remove from map
- //
-
- size_t one;
- one = sharedDbMap->erase(_mapKey);
- assert(one == 1);
-
- if(sharedDbMap->size() == 0)
- {
- delete sharedDbMap;
- sharedDbMap = 0;
- }
- }
-
- //
- // Keep lock to prevent somebody else to re-open this Db
- // before it's closed.
- //
- delete this;
- }
-}
-
-
-Freeze::SharedDb::SharedDb(const MapKey& mapKey,
- const string& key,
- const string& value,
- const ConnectionIPtr& connection,
- const KeyCompareBasePtr& keyCompare,
- const vector<MapIndexBasePtr>& indices,
- bool createDb) :
- Db(connection->dbEnv()->getEnv(), 0),
- _mapKey(mapKey),
- _refCount(0),
- _trace(connection->trace()),
- _keyCompare(keyCompare),
- _inMap(false)
-{
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "opening Db \"" << _mapKey.dbName << "\"";
- }
-
- Catalog catalog(connection, _catalogName);
-
- TransactionPtr tx = connection->currentTransaction();
- bool ownTx = (tx == 0);
-
- for(;;)
- {
- try
- {
- if(ownTx)
- {
- tx = 0;
- tx = connection->beginTransaction();
- }
-
- Catalog::iterator ci = catalog.find(_mapKey.dbName);
-
- if(ci != catalog.end())
- {
- if(ci->second.evictor)
- {
- throw DatabaseException(__FILE__, __LINE__, _mapKey.dbName + " is an evictor database");
- }
-
- _key = ci->second.key;
- _value = ci->second.value;
- checkTypes(*this, key, value);
- }
- else
- {
- _key = key;
- _value = value;
- }
-
- set_app_private(this);
- if(_keyCompare->compareEnabled())
- {
- set_bt_compare(&customCompare);
- }
-
- Ice::PropertiesPtr properties = _mapKey.communicator->getProperties();
- string propPrefix = "Freeze.Map." + _mapKey.dbName + ".";
-
- int btreeMinKey = properties->getPropertyAsInt(propPrefix + "BtreeMinKey");
- if(btreeMinKey > 2)
- {
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Setting \"" << _mapKey.dbName << "\"'s btree minkey to " << btreeMinKey;
- }
- set_bt_minkey(btreeMinKey);
- }
-
- bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0;
- if(checksum)
- {
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Turning checksum on for \"" << _mapKey.dbName << "\"";
- }
-
- set_flags(DB_CHKSUM);
- }
-
- int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize");
- if(pageSize > 0)
- {
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Setting \"" << _mapKey.dbName << "\"'s pagesize to " << pageSize;
- }
- set_pagesize(pageSize);
- }
-
-
- DbTxn* txn = getTxn(tx);
-
- u_int32_t flags = DB_THREAD;
- if(createDb)
- {
- flags |= DB_CREATE;
- }
- open(txn, _mapKey.dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE);
-
-
- Ice::StringSeq oldIndices;
- Ice::StringSeq newIndices;
- size_t oldSize = 0;
- CatalogIndexList catalogIndexList(connection, _catalogIndexListName);
-
- if(createDb)
- {
- CatalogIndexList::iterator cil = catalogIndexList.find(_mapKey.dbName);
- if(cil != catalogIndexList.end())
- {
- oldIndices = cil->second;
- oldSize = oldIndices.size();
- }
- }
-
- for(vector<MapIndexBasePtr>::const_iterator p = indices.begin();
- p != indices.end(); ++p)
- {
- const MapIndexBasePtr& indexBase = *p;
- assert(indexBase->_impl == 0);
- assert(indexBase->_communicator == 0);
- indexBase->_communicator = connection->communicator();
-
- auto_ptr<MapIndexI> indexI;
-
- try
- {
- indexI.reset(new MapIndexI(connection, *this, txn, createDb, indexBase));
- }
- catch(const DbDeadlockException&)
- {
- throw;
- }
- catch(const DbException& dx)
- {
- string message = "Error while opening index \"" + _mapKey.dbName +
- "." + indexBase->name() + "\": " + dx.what();
-
- throw DatabaseException(__FILE__, __LINE__, message);
- }
-
-#ifndef NDEBUG
- bool inserted =
-#endif
- _indices.insert(IndexMap::value_type(indexBase->name(), indexI.get())).second;
- assert(inserted);
-
- indexBase->_impl = indexI.release();
-
- if(createDb)
- {
- newIndices.push_back(indexBase->name());
- oldIndices.erase(std::remove(oldIndices.begin(), oldIndices.end(), indexBase->name()), oldIndices.end());
- }
- }
-
- if(ci == catalog.end())
- {
- CatalogData catalogData;
- catalogData.evictor = false;
- catalogData.key = key;
- catalogData.value = value;
- catalog.put(Catalog::value_type(_mapKey.dbName, catalogData));
- }
-
- if(createDb)
- {
- //
- // Remove old indices and write the new ones
- //
- bool indexRemoved = false;
-
- for(Ice::StringSeq::const_iterator q = oldIndices.begin(); q != oldIndices.end(); ++q)
- {
- const string& index = *q;
-
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "removing old index \"" << index << "\" on Db \"" << _mapKey.dbName << "\"";
- }
-
- try
- {
- connection->removeMapIndex(_mapKey.dbName, *q);
- indexRemoved = true;
- }
- catch(const IndexNotFoundException&)
- {
- // Ignored
-
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "index \"" << index << "\" on Db \"" << _mapKey.dbName << "\" does not exist";
- }
- }
- }
-
- if(indexRemoved || oldSize != newIndices.size())
- {
- if(newIndices.size() == 0)
- {
- catalogIndexList.erase(_mapKey.dbName);
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Removed catalogIndexList entry for Db \"" << _mapKey.dbName << "\"";
- }
-
- }
- else
- {
- catalogIndexList.put(CatalogIndexList::value_type(_mapKey.dbName, newIndices));
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Updated catalogIndexList entry for Db \"" << _mapKey.dbName << "\"";
- }
- }
- }
- }
-
- if(ownTx)
- {
- tx->commit();
- }
- break; // for(;;)
- }
- catch(const DbDeadlockException& dx)
- {
- if(ownTx)
- {
- if(connection->deadlockWarning())
- {
- Warning out(connection->communicator()->getLogger());
- out << "Deadlock in Freeze::SharedDb::SharedDb on Map \""
- << _mapKey.dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- else
- {
- throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
- }
- }
- catch(const DbException& dx)
- {
- if(ownTx)
- {
- try
- {
- tx->rollback();
- }
- catch(...)
- {
- }
- }
-
- string message = "Error while opening Db \"" + _mapKey.dbName +
- "\": " + dx.what();
-
- throw DatabaseException(__FILE__, __LINE__, message);
- }
- catch(...)
- {
- if(ownTx && tx != 0)
- {
- try
- {
- tx->rollback();
- }
- catch(...)
- {
- }
- }
- throw;
- }
- }
-}
-
-Freeze::SharedDb::SharedDb(const MapKey& mapKey, const string& keyTypeId, const string& valueTypeId, DbEnv* env) :
- Db(env, 0),
- _mapKey(mapKey),
- _key(keyTypeId),
- _value(valueTypeId),
- _refCount(0),
- _inMap(false)
-{
- _trace = _mapKey.communicator->getProperties()->getPropertyAsInt("Freeze.Trace.Map");
-
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "opening Db \"" << _mapKey.dbName << "\"";
- }
-
- try
- {
- Ice::PropertiesPtr properties = _mapKey.communicator->getProperties();
- string propPrefix = "Freeze.Map." + _mapKey.dbName + ".";
-
- int btreeMinKey = properties->getPropertyAsInt(propPrefix + "BtreeMinKey");
- if(btreeMinKey > 2)
- {
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Setting \"" << _mapKey.dbName << "\"'s btree minkey to " << btreeMinKey;
- }
- set_bt_minkey(btreeMinKey);
- }
-
- bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0;
- if(checksum)
- {
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Turning checksum on for \"" << _mapKey.dbName << "\"";
- }
-
- set_flags(DB_CHKSUM);
- }
-
- int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize");
- if(pageSize > 0)
- {
- if(_trace >= 1)
- {
- Trace out(_mapKey.communicator->getLogger(), "Freeze.Map");
- out << "Setting \"" << _mapKey.dbName << "\"'s pagesize to " << pageSize;
- }
- set_pagesize(pageSize);
- }
-
- u_int32_t flags = DB_THREAD | DB_CREATE | DB_AUTO_COMMIT;
- open(0, _mapKey.dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE);
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-}
-
-void
-Freeze::SharedDb::connectIndices(const vector<MapIndexBasePtr>& indices) const
-{
- for(vector<MapIndexBasePtr>::const_iterator p = indices.begin();
- p != indices.end(); ++p)
- {
- const MapIndexBasePtr& indexBase = *p;
- assert(indexBase->_impl == 0);
-
- IndexMap::const_iterator q = _indices.find(indexBase->name());
- assert(q != _indices.end());
- indexBase->_impl = q->second;
- indexBase->_communicator = _mapKey.communicator;
- }
-}
-
-void
-Freeze::SharedDb::cleanup(bool noThrow)
-{
- try
- {
- for(IndexMap::iterator p = _indices.begin(); p != _indices.end(); ++p)
- {
- delete p->second;
- }
- _indices.clear();
-
- close(0);
- }
- catch(const ::DbException& dx)
- {
- if(!noThrow)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- }
-}