summaryrefslogtreecommitdiff
path: root/cpp/src/Freeze/MapI.cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2015-11-13 16:53:57 -0330
committerDwayne Boone <dwayne@zeroc.com>2015-11-13 16:53:57 -0330
commit99c3941638f735825b1bfa9f2df764255351242b (patch)
treefdde43c6580b785e5edc9ae90c26487d9e16be13 /cpp/src/Freeze/MapI.cpp
parentadding registerIceBT (diff)
downloadice-99c3941638f735825b1bfa9f2df764255351242b.tar.bz2
ice-99c3941638f735825b1bfa9f2df764255351242b.tar.xz
ice-99c3941638f735825b1bfa9f2df764255351242b.zip
Moved Freeze to its own repository
Diffstat (limited to 'cpp/src/Freeze/MapI.cpp')
-rw-r--r--cpp/src/Freeze/MapI.cpp2121
1 files changed, 0 insertions, 2121 deletions
diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp
deleted file mode 100644
index 0b4ffa64a7d..00000000000
--- a/cpp/src/Freeze/MapI.cpp
+++ /dev/null
@@ -1,2121 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2015 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/MapI.h>
-#include <Freeze/MapDb.h>
-#include <Freeze/Exception.h>
-#include <Freeze/Util.h>
-#include <Freeze/TransactionHolder.h>
-#include <Freeze/Catalog.h>
-#include <Freeze/CatalogIndexList.h>
-#include <IceUtil/UUID.h>
-#include <IceUtil/StringConverter.h>
-#include <stdlib.h>
-
-using namespace std;
-using namespace Ice;
-using namespace Freeze;
-
-//
-// MapIndexBase (from Map.h)
-//
-
-Freeze::MapIndexBase::~MapIndexBase()
-{
-}
-
-Freeze::MapIndexBase::MapIndexBase(const string& name, bool enabled) :
- KeyCompareBase(enabled),
- _name(name),
- _impl(0),
- _map(0)
-{
-}
-
-const string&
-MapIndexBase::name() const
-{
- return _name;
-}
-
-IteratorHelper*
-Freeze::MapIndexBase::begin(bool ro) const
-{
- return _impl->begin(ro, *_map);
-}
-
-IteratorHelper*
-Freeze::MapIndexBase::untypedFind(const Key& k, bool ro, bool onlyDups) const
-{
- return _impl->untypedFind(k, ro, *_map, onlyDups);
-}
-
-IteratorHelper*
-Freeze::MapIndexBase::untypedLowerBound(const Key& k, bool ro) const
-{
- return _impl->untypedLowerBound(k, ro, *_map);
-}
-
-IteratorHelper*
-Freeze::MapIndexBase::untypedUpperBound(const Key& k, bool ro) const
-{
- return _impl->untypedUpperBound(k, ro, *_map);
-}
-
-int
-Freeze::MapIndexBase::untypedCount(const Key& k) const
-{
- return _impl->untypedCount(k, _map->connection());
-}
-
-//
-// KeyCompareBase
-//
-Freeze::KeyCompareBase::KeyCompareBase(bool enabled) :
- _enabled(enabled)
-{}
-
-bool
-Freeze::KeyCompareBase::compareEnabled() const
-{
- return _enabled;
-}
-
-//
-// MapHelper (from Map.h)
-//
-
-/*static*/ Freeze::MapHelper*
-Freeze::MapHelper::create(const Freeze::ConnectionPtr& connection,
- const string& dbName,
- const string& key,
- const string& value,
- const Freeze::KeyCompareBasePtr& keyCompare,
- const std::vector<MapIndexBasePtr>& indices,
- bool createDb)
-{
- Freeze::ConnectionIPtr connectionI = Freeze::ConnectionIPtr::dynamicCast(connection.get());
- return new MapHelperI(connectionI, dbName, key, value, keyCompare, indices, createDb);
-}
-
-/*static*/ void
-Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection,
- const string& dbName,
- const string& key,
- const string& value,
- const Freeze::KeyCompareBasePtr& keyCompare,
- const std::vector<MapIndexBasePtr>& indices)
-{
- Freeze::ConnectionIPtr connectionI = Freeze::ConnectionIPtr::dynamicCast(connection.get());
- if(connectionI == 0)
- {
- throw DatabaseException(__FILE__, __LINE__, "Invalid connection");
- }
-
- if(dbName == catalogName() || dbName == catalogIndexListName())
- {
- throw DatabaseException(__FILE__, __LINE__,
- "You cannot destroy recreate the \"" + dbName + "\" database");
- }
-
- if(connectionI->trace() >= 1)
- {
- Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
- out << "Recreating \"" << dbName << "\"";
- }
-
- TransactionPtr tx = connectionI->currentTransaction();
- bool ownTx = (tx == 0);
-
- Dbt keyDbt;
- keyDbt.set_flags(DB_DBT_REALLOC);
- Dbt valueDbt;
- valueDbt.set_flags(DB_DBT_REALLOC);
-
- try
- {
- for(;;)
- {
- try
- {
- if(ownTx)
- {
- tx = 0;
- tx = connectionI->beginTransaction();
- }
-
- DbTxn* txn = connectionI->dbTxn();
-
- if(connectionI->trace() >= 2)
- {
- Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
- out << "Removing all existing indices for \"" << dbName << "\"";
- }
- CatalogIndexList catalogIndexList(connection, catalogIndexListName());
- CatalogIndexList::iterator p = catalogIndexList.find(dbName);
- if(p != catalogIndexList.end())
- {
- const StringSeq& indices = p->second;
-
- for(size_t i = 0; i < indices.size(); ++i)
- {
- try
- {
- connection->removeMapIndex(dbName, indices[i]);
- }
- catch(const IndexNotFoundException&)
- {
- //
- // Ignored
- //
- }
- }
- catalogIndexList.erase(p);
- }
-
- //
- // Rename existing database
- //
- string oldDbName = dbName + ".old-" + IceUtil::generateUUID();
-
- if(connectionI->trace() >= 2)
- {
- Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
- out << "Renaming \"" << dbName << "\" to \"" << oldDbName << "\"";
- }
-
- connectionI->dbEnv()->getEnv()->dbrename(txn, dbName.c_str(), 0, oldDbName.c_str(), 0);
-
- //
- // Fortunately, DB closes oldDb automatically when it goes out of scope
- //
- Db oldDb(connectionI->dbEnv()->getEnv(), 0);
-
- //
- // Berkeley DB expects file paths to be UTF8 encoded.
- //
- oldDb.open(txn, IceUtil::nativeToUTF8(oldDbName, IceUtil::getProcessStringConverter()).c_str(),
- 0, DB_BTREE, DB_THREAD, FREEZE_DB_MODE);
-
- IceUtil::UniquePtr<MapDb> newDb(new MapDb(connectionI, dbName, key, value, keyCompare, indices, true));
-
- if(connectionI->trace() >= 2)
- {
- Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
- out << "Writing contents of \"" << oldDbName << "\" to fresh \"" << dbName << "\"";
- }
-
- //
- // Now simply write all of oldDb into newDb
- //
- Dbc* dbc = 0;
- oldDb.cursor(txn, &dbc, 0);
-
- try
- {
- while(dbc->get(&keyDbt, &valueDbt, DB_NEXT) == 0)
- {
- newDb->put(txn, &keyDbt, &valueDbt, 0);
- }
- }
- catch(...)
- {
- dbc->close();
- throw;
- }
- dbc->close();
-
- if(connectionI->trace() >= 2)
- {
- Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
- out << "Transfer complete; removing \"" << oldDbName << "\"";
- }
- connectionI->dbEnv()->getEnv()->dbremove(txn, oldDbName.c_str(), 0, 0);
-
- if(ownTx)
- {
- tx->commit();
- }
-
- break; // for (;;)
- }
- catch(const DbDeadlockException& dx)
- {
- if(ownTx)
- {
- if(connectionI->deadlockWarning())
- {
- Warning out(connectionI->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::recreate on Db \""
- << dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- else
- {
- throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
- }
- }
- catch(const DbException& dx)
- {
- if(ownTx)
- {
- try
- {
- tx->rollback();
- }
- catch(...)
- {
- }
- }
-
- throw DatabaseException(__FILE__, __LINE__, dx.what());
- }
- catch(...)
- {
- if(ownTx && tx != 0)
- {
- try
- {
- tx->rollback();
- }
- catch(...)
- {
- }
- }
- throw;
- }
- }
- free(keyDbt.get_data());
- free(valueDbt.get_data());
- }
- catch(...)
- {
- free(keyDbt.get_data());
- free(valueDbt.get_data());
-
- throw;
- }
-}
-
-Freeze::MapHelper::~MapHelper()
-{
-}
-
-//
-// IteratorHelper (from Map.h)
-//
-
-Freeze::IteratorHelper*
-Freeze::IteratorHelper::create(const MapHelper& m, bool readOnly)
-{
- const MapHelperI& actualMap = dynamic_cast<const MapHelperI&>(m);
-
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(actualMap, readOnly, 0, false));
- if(r->next())
- {
- return r.release();
- }
- else
- {
- return 0;
- }
-}
-
-Freeze::IteratorHelper::~IteratorHelper() ICE_NOEXCEPT_FALSE
-{
-}
-
-//
-// MapCodecBase (from Map.h)
-//
-Freeze::MapCodecBase::MapCodecBase(const Ice::CommunicatorPtr& communicator, const Ice::EncodingVersion& encoding) :
- _stream(IceInternal::getInstance(communicator).get(), encoding),
- _dbt(0)
-{
-}
-
-Freeze::MapCodecBase::~MapCodecBase()
-{
- delete _dbt;
-}
-
-void
-Freeze::MapCodecBase::init()
-{
- _dbt = new Dbt;
- initializeInDbt(_stream, *_dbt);
-}
-
-//
-// IteratorHelperI
-//
-
-Freeze::IteratorHelperI::IteratorHelperI(const MapHelperI& m, bool readOnly,
- const MapIndexBasePtr& index,
- bool onlyDups) :
- _map(m),
- _dbc(0),
- _indexed(index != 0),
- _onlyDups(onlyDups),
- _tx(0)
-{
- if(_map._trace >= 2)
- {
- Trace out(_map._connection->communicator()->getLogger(), "Freeze.Map");
- out << "opening iterator on Db \"" << _map._dbName << "\"";
- if(index != 0)
- {
- out << " with index \"" << index->name() << "\"";
- }
- }
-
- DbTxn* txn = _map._connection->dbTxn();
-
- if(txn == 0 && !readOnly)
- {
- //
- // Need to start a transaction
- //
-#ifdef ICE_CPP11
- _tx.reset(new Tx(_map));
-#else
- _tx = new Tx(_map);
-#endif
- txn = _tx->getTxn();
- }
-
- try
- {
- if(index != 0)
- {
- index->_impl->db()->cursor(txn, &_dbc, 0);
- }
- else
- {
- _map._db->cursor(txn, &_dbc, 0);
- }
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-
- _map._iteratorList.push_back(this);
-}
-
-Freeze::IteratorHelperI::IteratorHelperI(const IteratorHelperI& it) :
- _map(it._map),
- _dbc(0),
- _indexed(it._indexed),
- _onlyDups(it._onlyDups),
- _tx(0)
-{
- if(_map._trace >= 2)
- {
- Trace out(_map._connection->communicator()->getLogger(), "Freeze.Map");
- out << "duplicating iterator on Db \"" << _map._dbName << "\"";
- }
-
- try
- {
- it._dbc->dup(&_dbc, DB_POSITION);
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-
- _tx = it._tx;
- _map._iteratorList.push_back(this);
-}
-
-Freeze::IteratorHelperI::~IteratorHelperI() ICE_NOEXCEPT_FALSE
-{
- close();
-}
-
-bool
-Freeze::IteratorHelperI::find(const Key& key) const
-{
- Dbt dbKey;
- initializeInDbt(key, dbKey);
- return find(dbKey);
-}
-
-bool
-Freeze::IteratorHelperI::find(const Dbt& key) const
-{
- assert((key.get_flags() & DB_DBT_USERMEM) != 0);
- Dbt dbKey(key);
-
-#if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1)
- //
- // When we have a custom-comparison function, Berkeley DB returns
- // the key on-disk (when it finds one). We disable this behavior:
- // (ref Oracle SR 5925672.992)
- //
- dbKey.set_flags(dbKey.get_flags() | DB_DBT_PARTIAL);
-#else
- //
- // In DB > 5.1 we can not set DB_DBT_PARTIAL in the key Dbt,
- // when using DB_SET, we must resize the Dbt key param to hold enough
- // space or Dbc::get fails with DB_BUFFER_SMALL.
- //
- dbKey.set_ulen(dbKey.get_size());
-#endif
-
- //
- // Keep 0 length since we're not interested in the data.
- //
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- for(;;)
- {
- try
- {
- return _dbc->get(&dbKey, &dbValue, DB_SET) == 0;
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- }
-}
-
-bool
-Freeze::IteratorHelperI::lowerBound(const Key& key) const
-{
- //
- // We retrieve the actual key for upperBound
- //
- Dbt dbKey;
- _key = key;
- initializeOutDbt(_key, dbKey);
- dbKey.set_size(static_cast<u_int32_t>(_key.size()));
-
- //
- // Keep 0 length since we're not interested in the data
- //
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- for(;;)
- {
- try
- {
- int err = _dbc->get(&dbKey, &dbValue, DB_SET_RANGE);
- if(err == 0)
- {
- _key.resize(dbKey.get_size());
- return true;
- }
- else if(err == DB_NOTFOUND)
- {
- return false;
- }
- else
- {
- //
- // Bug in Freeze
- //
- assert(0);
- throw DatabaseException(__FILE__, __LINE__);
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- handleDbException(dx, _key, dbKey, __FILE__, __LINE__);
- }
- }
-}
-
-bool
-Freeze::IteratorHelperI::upperBound(const Key& key) const
-{
- if(lowerBound(key))
- {
- if(_key == key)
- {
- return next(true);
- }
- else
- {
- return true;
- }
- }
- else
- {
- return false;
- }
-}
-
-Freeze::IteratorHelper*
-Freeze::IteratorHelperI::clone() const
-{
- return new IteratorHelperI(*this);
-}
-
-void
-Freeze::IteratorHelperI::get(const Key*& key, const Value*& value) const
-{
- key = &_key;
- value = &_value;
-
- size_t keySize = _key.size();
- if(keySize < 1024)
- {
- keySize = 1024;
- }
- _key.resize(keySize);
-
- Dbt dbKey;
- initializeOutDbt(_key, dbKey);
-
- size_t valueSize = _value.size();
- if(valueSize < 1024)
- {
- valueSize = 1024;
- }
- _value.resize(valueSize);
- Dbt dbValue;
- initializeOutDbt(_value, dbValue);
-
- for(;;)
- {
- try
- {
- int err;
-
- if(_indexed)
- {
- //
- // Not interested in getting the index's key
- //
- Dbt iKey;
- iKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- err = _dbc->pget(&iKey, &dbKey, &dbValue, DB_CURRENT);
- }
- else
- {
- err = _dbc->get(&dbKey, &dbValue, DB_CURRENT);
- }
-
- if(err == 0)
- {
- _key.resize(dbKey.get_size());
- _value.resize(dbValue.get_size());
- break; // for(;;)
- }
- else if(err == DB_KEYEMPTY)
- {
- throw InvalidPositionException(__FILE__, __LINE__);
- }
- else
- {
- //
- // Bug in Freeze
- //
- assert(0);
- throw DatabaseException(__FILE__, __LINE__);
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- handleDbException(dx, _key, dbKey, _value, dbValue, __FILE__, __LINE__);
- }
- }
-}
-
-const Freeze::Key*
-Freeze::IteratorHelperI::get() const
-{
- size_t keySize = _key.size();
- if(keySize < 1024)
- {
- keySize = 1024;
- }
- _key.resize(keySize);
-
- Dbt dbKey;
- initializeOutDbt(_key, dbKey);
-
- //
- // Keep 0 length since we're not interested in the data
- //
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- for(;;)
- {
- try
- {
- int err;
- if(_indexed)
- {
- //
- // Not interested in getting the index's key
- //
- Dbt iKey;
- iKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- err = _dbc->pget(&iKey, &dbKey, &dbValue, DB_CURRENT);
- }
- else
- {
- err = _dbc->get(&dbKey, &dbValue, DB_CURRENT);
- }
-
- if(err == 0)
- {
- _key.resize(dbKey.get_size());
- return &_key;
- }
- else if(err == DB_KEYEMPTY)
- {
- throw InvalidPositionException(__FILE__, __LINE__);
- }
- else
- {
- //
- // Bug in Freeze
- //
- assert(0);
- throw DatabaseException(__FILE__, __LINE__);
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- handleDbException(dx, _key, dbKey, __FILE__, __LINE__);
- }
- }
-}
-
-void
-Freeze::IteratorHelperI::set(const Value& value)
-{
- Dbt dbValue;
- initializeInDbt(value, dbValue);
- set(dbValue);
-}
-
-void
-Freeze::IteratorHelperI::set(const Dbt& value)
-{
- if(_indexed)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = "Cannot set an iterator retrieved through an index";
- throw ex;
- }
-
- //
- // key ignored
- //
- Dbt dbKey;
- dbKey.set_flags(DB_DBT_USERMEM);
-
- Dbt dbValue(value);
-
- if(_tx != 0)
- {
- _map.closeAllIteratorsExcept(_tx);
- }
-
- try
- {
-#ifndef NDEBUG
- int err = _dbc->put(&dbKey, &dbValue, DB_CURRENT);
- assert(err == 0);
-#else
- _dbc->put(&dbKey, &dbValue, DB_CURRENT);
-#endif
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-}
-
-void
-Freeze::IteratorHelperI::erase()
-{
- if(_tx != 0)
- {
- _map.closeAllIteratorsExcept(_tx);
- }
-
- try
- {
- int err = _dbc->del(0);
- if(err == DB_KEYEMPTY)
- {
- throw InvalidPositionException(__FILE__, __LINE__);
- }
- assert(err == 0);
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-}
-
-bool
-Freeze::IteratorHelperI::next() const
-{
- return next(false);
-}
-
-bool
-Freeze::IteratorHelperI::next(bool skipDups) const
-{
- //
- // Keep 0 length since we're not interested in the data
- //
- Dbt dbKey;
- dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- int flags = DB_NEXT;
- if(skipDups)
- {
- flags = DB_NEXT_NODUP;
- }
- else if(_indexed && _onlyDups)
- {
- flags = DB_NEXT_DUP;
- }
-
- try
- {
- if(_dbc->get(&dbKey, &dbValue, flags) == 0)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_tx != 0)
- {
- _tx->dead();
- }
-
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-}
-
-void
-Freeze::IteratorHelperI::close()
-{
- if(_dbc != 0)
- {
- if(_map._trace >= 2)
- {
- Trace out(_map._connection->communicator()->getLogger(), "Freeze.Map");
- out << "closing iterator on Db \"" << _map._dbName << "\"";
- }
-
- try
- {
- _dbc->close();
- }
- catch(const ::DbDeadlockException&)
- {
- // Ignored - it's unclear if this can ever occur
- }
- catch(const ::DbException& dx)
- {
- cleanup();
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- cleanup();
- }
-}
-
-void
-Freeze::IteratorHelperI::cleanup()
-{
- _dbc = 0;
- _map._iteratorList.remove(this);
-
- // this can raise an exception when committing the transaction
- // (only for read/write iterators)
-#ifdef ICE_CPP11
- _tx.reset();
-#else
- _tx = 0;
-#endif
-}
-
-//
-// IteratorHelperI::Tx
-//
-
-Freeze::IteratorHelperI::Tx::Tx(const MapHelperI& m) :
- _map(m),
- _txn(0),
- _dead(false)
-{
- if(_map._trace >= 2)
- {
- Trace out(_map._connection->communicator()->getLogger(), "Freeze.Map");
- out << "starting transaction for Db \"" << _map._dbName << "\"";
- }
-
- try
- {
- _map._connection->dbEnv()->getEnv()->txn_begin(0, &_txn, 0);
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-}
-
-Freeze::IteratorHelperI::Tx::~Tx() ICE_NOEXCEPT_FALSE
-{
- if(_dead)
- {
- if(_map._trace >= 2)
- {
- Trace out(_map._connection->communicator()->getLogger(), "");
- out << "aborting transaction for Db \"" << _map._dbName << "\"";
- }
-
- try
- {
- _txn->abort();
- }
- catch(...)
- {
- //
- // Ignore exceptions to avoid crash during stack unwinding
- //
- }
- }
- else
- {
- if(_map._trace >= 2)
- {
- Trace out(_map._connection->communicator()->getLogger(), "Freeze.Map");
- out << "committing transaction for Db \"" << _map._dbName.c_str() << "\"";
- }
-
- try
- {
- _txn->commit(0);
- }
- catch(const ::DbDeadlockException& dx)
- {
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- }
-}
-
-void
-Freeze::IteratorHelperI::Tx::dead()
-{
- _dead = true;
-}
-
-//
-// MapHelperI
-//
-
-Freeze::MapHelperI::MapHelperI(const ConnectionIPtr& connection,
- const string& dbName,
- const string& key,
- const string& value,
- const KeyCompareBasePtr& keyCompare,
- const vector<MapIndexBasePtr>& indices,
- bool createDb) :
- _connection(connection),
- _db(connection->dbEnv()->getSharedMapDb(dbName, key, value, keyCompare, indices, createDb)),
- _dbName(dbName),
- _trace(connection->trace())
-{
- for(vector<MapIndexBasePtr>::const_iterator p = indices.begin();
- p != indices.end(); ++p)
- {
- const MapIndexBasePtr& indexBase = *p;
- assert(indexBase->_impl != 0);
- assert(indexBase->_communicator == _connection->communicator());
- assert(indexBase->_map == 0);
-
-#ifdef NDEBUG
- _indices.insert(IndexMap::value_type(indexBase->name(), indexBase));
-#else
- bool inserted = _indices.insert(IndexMap::value_type(indexBase->name(), indexBase)).second;
- assert(inserted);
-#endif
-
- indexBase->_map = this;
- }
-
- _connection->registerMap(this);
-}
-
-Freeze::MapHelperI::~MapHelperI()
-{
- try
- {
- close();
- }
- catch(const DatabaseException& ex)
- {
- Ice::Error error(_connection->getCommunicator()->getLogger());
- error << "Freeze: closing map " << _dbName << " raised: " << ex;
- }
-}
-
-Freeze::IteratorHelper*
-Freeze::MapHelperI::find(const Key& k, bool readOnly) const
-{
- for(;;)
- {
- try
- {
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false));
- if(r->find(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
- }
- catch(const DeadlockException&)
- {
- if(_connection->dbTxn() != 0)
- {
- throw;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::find on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- }
-}
-
-Freeze::IteratorHelper*
-Freeze::MapHelperI::find(const Dbt& k, bool readOnly) const
-{
- for(;;)
- {
- try
- {
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false));
- if(r->find(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
- }
- catch(const DeadlockException&)
- {
- if(_connection->dbTxn() != 0)
- {
- throw;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::find on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- }
-}
-
-Freeze::IteratorHelper*
-Freeze::MapHelperI::lowerBound(const Key& k, bool readOnly) const
-{
- for(;;)
- {
- try
- {
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false));
- if(r->lowerBound(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
- }
- catch(const DeadlockException&)
- {
- if(_connection->dbTxn() != 0)
- {
- throw;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::lowerBound on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- }
-}
-
-Freeze::IteratorHelper*
-Freeze::MapHelperI::upperBound(const Key& k, bool readOnly) const
-{
- for(;;)
- {
- try
- {
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(*this, readOnly, 0, false));
- if(r->upperBound(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
- }
- catch(const DeadlockException&)
- {
- if(_connection->dbTxn() != 0)
- {
- throw;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::upperBound on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- }
-}
-
-void
-Freeze::MapHelperI::put(const Key& key, const Value& value)
-{
- Dbt dbKey;
- Dbt dbValue;
- initializeInDbt(key, dbKey);
- initializeInDbt(value, dbValue);
- put(dbKey, dbValue);
-}
-
-void
-Freeze::MapHelperI::put(const Dbt& key, const Dbt& value)
-{
- DbTxn* txn = _connection->dbTxn();
- if(txn == 0)
- {
- closeAllIterators();
- }
-
- Dbt dbKey(key);
- Dbt dbValue(value);
-
- for(;;)
- {
- try
- {
- int err = _db->put(txn, &dbKey, &dbValue, txn != 0 ? 0 : DB_AUTO_COMMIT);
-
- if(err == 0)
- {
- break;
- }
- else
- {
- //
- // Bug in Freeze
- //
- throw DatabaseException(__FILE__, __LINE__);
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(txn != 0)
- {
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::put on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- }
-}
-
-size_t
-Freeze::MapHelperI::erase(const Key& key)
-{
- Dbt dbKey;
- initializeInDbt(key, dbKey);
- return erase(dbKey);
-}
-
-size_t
-Freeze::MapHelperI::erase(const Dbt& key)
-{
- DbTxn* txn = _connection->dbTxn();
- if(txn == 0)
- {
- closeAllIterators();
- }
-
- Dbt dbKey(key);
-
- for(;;)
- {
- try
- {
- int err = _db->del(txn, &dbKey, txn != 0 ? 0 : DB_AUTO_COMMIT);
-
- if(err == 0)
- {
- return 1;
- }
- else if(err == DB_NOTFOUND)
- {
- return 0;
- }
- else
- {
- assert(0);
- throw DatabaseException(__FILE__, __LINE__);
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(txn != 0)
- {
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::erase on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- }
-}
-
-size_t
-Freeze::MapHelperI::count(const Key& key) const
-{
- Dbt dbKey;
- initializeInDbt(key, dbKey);
- return count(dbKey);
-}
-
-size_t
-Freeze::MapHelperI::count(const Dbt& key) const
-{
- Dbt dbKey(key);
-
- //
- // Keep 0 length since we're not interested in the data
- //
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- for(;;)
- {
- try
- {
- int err = _db->get(_connection->dbTxn(), &dbKey, &dbValue, 0);
-
- if(err == 0)
- {
- return 1;
- }
- else if(err == DB_NOTFOUND)
- {
- return 0;
- }
- else
- {
- assert(0);
- throw DatabaseException(__FILE__, __LINE__);
- }
- }
- catch(const ::DbDeadlockException& dx)
- {
- if(_connection->dbTxn() != 0)
- {
- DeadlockException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- else
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::count on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- }
-}
-
-void
-Freeze::MapHelperI::clear()
-{
- DbTxn* txn = _connection->dbTxn();
- if(txn == 0)
- {
- closeAllIterators();
- }
-
- Dbt dbKey;
- dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- try
- {
- for(;;)
- {
- Dbc* dbc = 0;
-
- try
- {
- IteratorHelperI::TxPtr tx;
- if(txn == 0)
- {
-#ifdef ICE_CPP11
- tx.reset(new IteratorHelperI::Tx(*this));
-#else
- tx = new IteratorHelperI::Tx(*this);
-#endif
- txn = tx->getTxn();
- }
-
- _db->cursor(txn, &dbc, 0);
- while(dbc->get(&dbKey, &dbValue, DB_NEXT | DB_RMW) == 0)
- {
- dbc->del(0);
- }
-
- Dbc* toClose = dbc;
- dbc = 0;
- toClose->close();
- break; // for (;;)
- }
- catch(const DbDeadlockException&)
- {
- if(dbc != 0)
- {
- try
- {
- dbc->close();
- }
- catch(const DbDeadlockException&)
- {
- if(txn != 0)
- {
- throw;
- }
- else
- {
- //
- // Ignored
- //
- }
- }
- }
-
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::clear on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- if(txn != 0)
- {
- throw;
- }
- //
- // Otherwise retry
- //
- }
- catch(...)
- {
- if(dbc != 0)
- {
- try
- {
- dbc->close();
- }
- catch(const DbDeadlockException&)
- {
- if(txn != 0)
- {
- throw;
- }
- else
- {
- //
- // Ignored
- //
- }
- }
- }
- throw;
- }
- }
- }
- catch(const DbDeadlockException& dx)
- {
- throw DeadlockException(__FILE__, __LINE__, dx.what(), _connection->currentTransaction());
- }
- catch(const DbException& dx)
- {
- throw DatabaseException(__FILE__, __LINE__, dx.what());
- }
-}
-
-void
-Freeze::MapHelperI::destroy()
-{
- if(_dbName == catalogName() || _dbName == catalogIndexListName())
- {
- throw DatabaseException(__FILE__, __LINE__, "You cannot destroy the \"" + _dbName + "\" database");
- }
-
- if(_db == 0)
- {
- //
- // We need an opened map to gather the index names
- //
- throw DatabaseException(__FILE__, __LINE__, "This map is closed");
- }
-
- if(_connection->currentTransaction())
- {
- throw DatabaseException(__FILE__, __LINE__, "Cannot destroy map within transaction");
- }
-
- if(_trace >= 1)
- {
- Trace out(_connection->communicator()->getLogger(), "Freeze.Map");
- out << "Destroying \"" << _dbName << "\"";
- }
-
- vector<string> indexNames;
- for(IndexMap::iterator p = _indices.begin(); p != _indices.end(); ++p)
- {
- indexNames.push_back(p->second->name());
- }
-
- closeDb();
-
- for(;;)
- {
- try
- {
- TransactionHolder tx(_connection);
- DbTxn* txn = _connection->dbTxn();
-
- Catalog catalog(_connection, catalogName());
- catalog.erase(_dbName);
-
- CatalogIndexList catalogIndexList(_connection, catalogIndexListName());
- catalogIndexList.erase(_dbName);
-
- _connection->dbEnv()->getEnv()->dbremove(txn, _dbName.c_str(), 0, 0);
-
- //
- // Remove all indices
- //
- for(vector<string>::iterator q = indexNames.begin(); q != indexNames.end(); ++q)
- {
- _connection->removeMapIndex(_dbName, *q);
- }
-
- tx.commit();
-
- break; // for(;;)
- }
- catch(const DbDeadlockException&)
- {
- if(_connection->deadlockWarning())
- {
- Warning out(_connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapHelperI::destroy on Map \""
- << _dbName << "\"; retrying ...";
- }
-
- //
- // Ignored, try again
- //
- }
- catch(const DbException& dx)
- {
- throw DatabaseException(__FILE__, __LINE__, dx.what());
- }
- }
-}
-
-size_t
-Freeze::MapHelperI::size() const
-{
- DB_BTREE_STAT* s;
-
- try
- {
-#if DB_VERSION_MAJOR < 4
-#error Freeze requires DB 4.x or greater
-#endif
-#if (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR < 3)
- _db->stat(&s, 0);
-#else
- _db->stat(_connection->dbTxn(), &s, 0);
-#endif
- }
- catch(const ::DbException& dx)
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
-
- size_t num = s->bt_ndata;
- free(s);
- return num;
-}
-
-void
-Freeze::MapHelperI::closeAllIterators()
-{
- while(!_iteratorList.empty())
- {
- (*_iteratorList.begin())->close();
- }
-}
-
-const MapIndexBasePtr&
-Freeze::MapHelperI::index(const string& name) const
-{
- IndexMap::const_iterator p = _indices.find(name);
- if(p == _indices.end())
- {
- DatabaseException ex(__FILE__, __LINE__);
- ex.message = "Cannot find index \"" + name + "\"";
- throw ex;
- }
- return p->second;
-}
-
-void
-Freeze::MapHelperI::closeDb()
-{
- close();
- _connection->dbEnv()->removeSharedMapDb(_dbName);
-}
-
-Freeze::ConnectionPtr
-Freeze::MapHelperI::getConnection() const
-{
- return _connection;
-}
-
-void
-Freeze::MapHelperI::close()
-{
- if(_db != 0)
- {
- closeAllIterators();
- _connection->unregisterMap(this);
- }
- _db = 0;
-
- //
- // We can't clear the indexBase as MapIndexI is using
- // the first map's indexBase objects
- //
- _indices.clear();
-}
-
-void
-Freeze::MapHelperI::closeAllIteratorsExcept(const IteratorHelperI::TxPtr& tx) const
-{
- assert(tx != 0);
-
- list<IteratorHelperI*>::iterator q = _iteratorList.begin();
-
- while(q != _iteratorList.end())
- {
- if((*q)->tx().get() == tx.get())
- {
- ++q;
- }
- else
- {
- (*q)->close();
- q = _iteratorList.begin();
- }
- }
-}
-
-//
-// MapIndexI
-//
-
-extern "C"
-{
-#if (DB_VERSION_MAJOR <= 5)
- static int customIndexCompare(DB* db, const DBT* dbt1, const DBT* dbt2)
-#else
- static int customIndexCompare(DB* db, const DBT* dbt1, const DBT* dbt2, size_t*)
-#endif
- {
- MapIndexI* me = static_cast<MapIndexI*>(db->app_private);
- Byte* first = static_cast<Byte*>(dbt1->data);
- Key k1(first, first + dbt1->size);
- first = static_cast<Byte*>(dbt2->data);
- Key k2(first, first + dbt2->size);
-
- return me->getKeyCompare()->compare(k1, k2);
- }
-}
-
-static int
-callback(Db* secondary, const Dbt* key, const Dbt* value, Dbt* result)
-{
- void* indexObj = secondary->get_app_private();
- MapIndexI* index = static_cast<MapIndexI*>(indexObj);
- assert(index != 0);
- return index->secondaryKeyCreate(secondary, key, value, result);
-}
-
-Freeze::MapIndexI::MapIndexI(const ConnectionIPtr& connection, MapDb& db,
- DbTxn* txn, bool createDb, const MapIndexBasePtr& index) :
- _index(index)
-{
- assert(txn != 0);
-
- _db.reset(new Db(connection->dbEnv()->getEnv(), 0));
- _db->set_flags(DB_DUP | DB_DUPSORT);
-
- u_int32_t flags = 0;
- if(createDb)
- {
- flags = DB_CREATE;
- }
-
- _dbName = db.dbName() + "." + _index->name();
-
- _db->set_app_private(this);
-
- if(index->compareEnabled())
- {
- _db->set_bt_compare(&customIndexCompare);
- }
-
- Ice::PropertiesPtr properties = connection->communicator()->getProperties();
- string propPrefix = "Freeze.Map." + _dbName + ".";
- int btreeMinKey = properties->getPropertyAsInt(propPrefix + "BtreeMinKey");
- if(btreeMinKey > 2)
- {
- if(connection->trace() >= 1)
- {
- Trace out(connection->communicator()->getLogger(), "Freeze.Map");
- out << "Setting \"" << _dbName << "\"'s btree minkey to " << btreeMinKey;
- }
-
- _db->set_bt_minkey(btreeMinKey);
- }
-
- bool checksum = properties->getPropertyAsInt(propPrefix + "Checksum") > 0;
- if(checksum)
- {
- if(connection->trace() >= 1)
- {
- Trace out(connection->communicator()->getLogger(), "Freeze.Map");
- out << "Turning checksum on for \"" << _dbName << "\"";
- }
-
- _db->set_flags(DB_CHKSUM);
- }
-
- int pageSize = properties->getPropertyAsInt(propPrefix + "PageSize");
- if(pageSize > 0)
- {
- if(connection->trace() >= 1)
- {
- Trace out(connection->communicator()->getLogger(), "Freeze.Map");
- out << "Setting \"" << _dbName << "\"'s pagesize to " << pageSize;
- }
-
- _db->set_pagesize(pageSize);
- }
-
- if(connection->trace() >= 1)
- {
- Trace out(connection->communicator()->getLogger(), "Freeze.Map");
- out << "Opening index \"" << _dbName << "\"";
- }
-
- //
- // Berkeley DB expects file paths to be UTF8 encoded.
- //
- _db->open(txn, IceUtil::nativeToUTF8(_dbName, IceUtil::getProcessStringConverter()).c_str(), 0, DB_BTREE, flags,
- FREEZE_DB_MODE);
-
- //
- // To populate empty indices
- //
- flags = DB_CREATE;
- db.associate(txn, _db.get(), callback, flags);
-
- //
- // Note: caller catch and translates exceptions
- //
-}
-
-Freeze::MapIndexI::~MapIndexI()
-{
- try
- {
- _db->close(0);
- }
- catch(const DbException&)
- {
- // Ignored
- }
-}
-
-IteratorHelper*
-Freeze::MapIndexI::begin(bool ro, const MapHelperI& m) const
-{
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, false));
-
- if(r->next())
- {
- return r.release();
- }
- else
- {
- return 0;
- }
-}
-
-IteratorHelper*
-Freeze::MapIndexI::untypedFind(const Key& k, bool ro, const MapHelperI& m, bool onlyDups) const
-{
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, onlyDups));
-
- if(r->find(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
-}
-
-IteratorHelper*
-Freeze::MapIndexI::untypedLowerBound(const Key& k, bool ro, const MapHelperI& m) const
-{
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, false));
-
- if(r->lowerBound(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
-}
-
-IteratorHelper*
-Freeze::MapIndexI::untypedUpperBound(const Key& k, bool ro, const MapHelperI& m) const
-{
- IceUtil::UniquePtr<IteratorHelperI> r(new IteratorHelperI(m, ro, _index, false));
-
- if(r->upperBound(k))
- {
- return r.release();
- }
- else
- {
- return 0;
- }
-}
-
-int
-Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) const
-{
- Dbt dbKey;
- initializeInDbt(k, dbKey);
-#if (DB_VERSION_MAJOR <= 4)
- //
- // When we have a custom-comparison function, Berkeley DB returns
- // the key on-disk (when it finds one). We disable this behavior:
- // (ref Oracle SR 5925672.992)
- //
- dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-#else
- //
- // In DB 5.x we can not set DB_DBT_PARTIAL in the key Dbt,
- // when using DB_SET, we must resize the Dbt key param to hold enought
- // space or Dbc::get fails with DB_BUFFER_SMALL.
- //
- dbKey.set_flags(DB_DBT_USERMEM);
- dbKey.set_ulen(static_cast<u_int32_t>(k.size()));
-#endif
-
- Dbt dbValue;
- dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
-
- int result = 0;
-
- DbTxn* txn = connection->dbTxn();
-
- try
- {
- for(;;)
- {
- Dbc* dbc = 0;
-
- try
- {
- //
- // Move to the first record
- //
- _db->cursor(txn, &dbc, 0);
- bool found = (dbc->get(&dbKey, &dbValue, DB_SET) == 0);
-
- if(found)
- {
- db_recno_t count = 0;
- dbc->count(&count, 0);
- result = static_cast<int>(count);
- }
-
- Dbc* toClose = dbc;
- dbc = 0;
- toClose->close();
- break; // for (;;)
- }
- catch(const DbDeadlockException&)
- {
- if(dbc != 0)
- {
- try
- {
- dbc->close();
- }
- catch(const DbDeadlockException&)
- {
- if(txn != 0)
- {
- throw;
- }
- else
- {
- //
- // Ignored
- //
- }
- }
- }
-
- if(connection->deadlockWarning())
- {
- Warning out(connection->communicator()->getLogger());
- out << "Deadlock in Freeze::MapIndexI::untypedCount while searching \""
- << _dbName << "\"";
- }
-
- if(txn != 0)
- {
- throw;
- }
- //
- // Otherwise retry
- //
- }
- catch(...)
- {
- if(dbc != 0)
- {
- try
- {
- dbc->close();
- }
- catch(const DbDeadlockException&)
- {
- if(txn != 0)
- {
- throw;
- }
- else
- {
- //
- // Ignored
- //
- }
- }
- }
- throw;
- }
- }
- }
- catch(const DbDeadlockException& dx)
- {
- throw DeadlockException(__FILE__, __LINE__, dx.what(), connection->currentTransaction());
- }
- catch(const DbException& dx)
- {
- throw DatabaseException(__FILE__, __LINE__, dx.what());
- }
-
- return result;
-}
-
-int
-Freeze::MapIndexI::secondaryKeyCreate(Db* /*secondary*/, const Dbt* /*dbKey*/, const Dbt* dbValue, Dbt* result)
-{
- Byte* first = static_cast<Byte*>(dbValue->get_data());
- Value value(first, first + dbValue->get_size());
-
- Key bytes;
- _index->marshalKey(value, bytes);
-
- result->set_flags(DB_DBT_APPMALLOC);
- void* data = malloc(bytes.size());
- memcpy(data, &bytes[0], bytes.size());
- result->set_data(data);
- result->set_size(static_cast<u_int32_t>(bytes.size()));
- return 0;
-}
-
-//
-// Print for the various exception types.
-//
-void
-Freeze::DeadlockException::ice_print(ostream& out) const
-{
- Exception::ice_print(out);
- out << ":\ndatabase deadlock:\n" << message;
-}
-
-void
-Freeze::NotFoundException::ice_print(ostream& out) const
-{
- Exception::ice_print(out);
- out << ":\ndatabase record not found:\n" << message;
-}
-
-void
-Freeze::DatabaseException::ice_print(ostream& out) const
-{
- Exception::ice_print(out);
- out << ":\n" << message;
-}
-
-void
-Freeze::IndexNotFoundException::ice_print(ostream& out) const
-{
- Exception::ice_print(out);
- out << ":\ncould not find index \"" << indexName << "\" on map \"" << mapName << "\"";
-}