summaryrefslogtreecommitdiff
path: root/cpp/src/Freeze/MapI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Freeze/MapI.cpp')
-rw-r--r--cpp/src/Freeze/MapI.cpp391
1 files changed, 214 insertions, 177 deletions
diff --git a/cpp/src/Freeze/MapI.cpp b/cpp/src/Freeze/MapI.cpp
index daf9358f493..a473af868bb 100644
--- a/cpp/src/Freeze/MapI.cpp
+++ b/cpp/src/Freeze/MapI.cpp
@@ -14,20 +14,13 @@
#include <Freeze/MapI.h>
#include <Freeze/DBException.h>
-#include <sys/stat.h>
+#include <Freeze/SharedDb.h>
#include <stdlib.h>
using namespace std;
using namespace Ice;
using namespace Freeze;
-#ifdef _WIN32
-# define FREEZE_DB_MODE 0
-#else
-# define FREEZE_DB_MODE (S_IRUSR | S_IWUSR)
-#endif
-
-
namespace
{
@@ -62,27 +55,12 @@ initializeOutDbt(vector<Ice::Byte>& v, Dbt& dbt)
//
Freeze::DBMapHelper*
-Freeze::DBMapHelper::create(const CommunicatorPtr& communicator,
- const string& envName,
+Freeze::DBMapHelper::create(const Freeze::ConnectionPtr& connection,
const string& dbName,
bool createDb)
{
- return new DBMapHelperI(communicator, envName, dbName, createDb);
-}
-
-Freeze::DBMapHelper*
-Freeze::DBMapHelper::create(const CommunicatorPtr& communicator,
- DbEnv& dbEnv,
- const string& dbName,
- bool createDb)
-{
- return new DBMapHelperI(communicator, dbEnv, dbName, createDb);
-}
-
-
-Freeze::DBMapHelper::DBMapHelper(const Ice::CommunicatorPtr& communicator) :
- _communicator(communicator)
-{
+ Freeze::ConnectionIPtr connectionI = Freeze::ConnectionIPtr::dynamicCast(connection);
+ return new DBMapHelperI(connectionI, dbName, createDb);
}
Freeze::DBMapHelper::~DBMapHelper()
@@ -127,16 +105,15 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBMapHelperI& m, bool readOnl
_dbc(0),
_tx(0)
{
-
if(_map._trace >= 3)
{
- Trace out(_map._communicator->getLogger(), "DB");
- out << "opening iterator on database \"" << _map._dbName.c_str() << "\"";
+ Trace out(_map._connection->communicator()->getLogger(), "DB");
+ out << "opening iterator on database \"" << _map._dbName << "\"";
}
- DbTxn* txn = 0;
+ DbTxn* txn = _map._connection->dbTxn();
- if(!readOnly)
+ if(txn == 0 && !readOnly)
{
//
// Need to start a transaction
@@ -147,7 +124,7 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBMapHelperI& m, bool readOnl
try
{
- m._db.get()->cursor(txn, &_dbc, 0);
+ _map._db->cursor(txn, &_dbc, 0);
}
catch(const ::DbException& dx)
{
@@ -155,6 +132,7 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBMapHelperI& m, bool readOnl
ex.message = dx.what();
throw ex;
}
+ _map._iteratorList.push_back(this);
}
Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBIteratorHelperI& it) :
@@ -164,8 +142,8 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBIteratorHelperI& it) :
{
if(_map._trace >= 3)
{
- Trace out(_map._communicator->getLogger(), "DB");
- out << "duplicating iterator on database \"" << _map._dbName.c_str() << "\"";
+ Trace out(_map._connection->communicator()->getLogger(), "DB");
+ out << "duplicating iterator on database \"" << _map._dbName << "\"";
}
try
@@ -180,33 +158,12 @@ Freeze::DBIteratorHelperI::DBIteratorHelperI(const DBIteratorHelperI& it) :
}
_tx = it._tx;
+ _map._iteratorList.push_back(this);
}
Freeze::DBIteratorHelperI::~DBIteratorHelperI()
{
- if(_map._trace >= 3)
- {
- Trace out(_map._communicator->getLogger(), "DB");
- out << "closing iterator on database \"" << _map._dbName.c_str() << "\"";
- }
-
- try
- {
- _dbc->close();
- }
- catch(const ::DbDeadlockException&)
- {
- // Ignored
- }
- catch(const ::DbException& dx)
- {
- DBException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- _dbc = 0;
-
- _tx = 0;
+ close();
}
bool
@@ -461,6 +418,11 @@ Freeze::DBIteratorHelperI::set(const Value& value)
Dbt dbValue;
initializeInDbt(value, dbValue);
+ if(_tx != 0)
+ {
+ _map.closeAllIteratorsExcept(_tx);
+ }
+
try
{
int err = _dbc->put(&dbKey, &dbValue, DB_CURRENT);
@@ -488,6 +450,11 @@ Freeze::DBIteratorHelperI::set(const Value& value)
void
Freeze::DBIteratorHelperI::erase()
{
+ if(_tx != 0)
+ {
+ _map.closeAllIteratorsExcept(_tx);
+ }
+
try
{
int err = _dbc->del(0);
@@ -581,17 +548,56 @@ Freeze::DBIteratorHelperI::equals(const DBIteratorHelper& rhs) const
}
}
-const Ice::CommunicatorPtr&
-Freeze::DBIteratorHelperI::getCommunicator() const
+void
+Freeze::DBIteratorHelperI::close()
+{
+ if(_dbc != 0)
+ {
+ if(_map._trace >= 3)
+ {
+ Trace out(_map._connection->communicator()->getLogger(), "DB");
+ out << "closing iterator on database \"" << _map._dbName << "\"";
+ }
+
+ try
+ {
+ _dbc->close();
+ }
+ catch(const ::DbDeadlockException& dx)
+ {
+ bool raiseException = (_tx == 0);
+ cleanup();
+ if(raiseException)
+ {
+ DBDeadlockException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+ }
+ catch(const ::DbException& dx)
+ {
+ cleanup();
+ DBException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+ cleanup();
+ }
+}
+
+void
+Freeze::DBIteratorHelperI::cleanup()
{
- return _map._communicator;
+ _dbc = 0;
+ _map._iteratorList.remove(this);
+ _tx = 0;
}
+
//
// DBIteratorHelperI::Tx
//
-
Freeze::DBIteratorHelperI::Tx::Tx(const DBMapHelperI& m) :
_map(m),
_txn(0),
@@ -599,13 +605,13 @@ Freeze::DBIteratorHelperI::Tx::Tx(const DBMapHelperI& m) :
{
if(_map._trace >= 3)
{
- Trace out(_map._communicator->getLogger(), "DB");
- out << "starting transaction for database \"" << _map._dbName.c_str() << "\"";
+ Trace out(_map._connection->communicator()->getLogger(), "DB");
+ out << "starting transaction for database \"" << _map._dbName << "\"";
}
try
{
- _map._dbEnv->txn_begin(0, &_txn, 0);
+ _map._connection->dbEnv()->txn_begin(0, &_txn, 0);
}
catch(const ::DbException& dx)
{
@@ -622,8 +628,8 @@ Freeze::DBIteratorHelperI::Tx::~Tx()
{
if(_map._trace >= 3)
{
- Trace out(_map._communicator->getLogger(), "DB");
- out << "aborting transaction for database \"" << _map._dbName.c_str() << "\"";
+ Trace out(_map._connection->communicator()->getLogger(), "DB");
+ out << "aborting transaction for database \"" << _map._dbName << "\"";
}
try
@@ -641,7 +647,7 @@ Freeze::DBIteratorHelperI::Tx::~Tx()
{
if(_map._trace >= 3)
{
- Trace out(_map._communicator->getLogger(), "DB");
+ Trace out(_map._connection->communicator()->getLogger(), "DB");
out << "committing transaction for database \"" << _map._dbName.c_str() << "\"";
}
@@ -667,11 +673,6 @@ Freeze::DBIteratorHelperI::Tx::~Tx()
void
Freeze::DBIteratorHelperI::Tx::dead()
{
- //
- // No need for synchronization since DBIteratorHelperI is not
- // thread-safe (see Berkeley DB doc)
- //
-
_dead = true;
}
@@ -682,87 +683,20 @@ Freeze::DBIteratorHelperI::Tx::dead()
//
-Freeze::DBMapHelperI::DBMapHelperI(const CommunicatorPtr& communicator,
- const string& envName,
- const string& dbName,
+Freeze::DBMapHelperI::DBMapHelperI(const ConnectionIPtr& connection,
+ const std::string& dbName,
bool createDb) :
- DBMapHelper(communicator),
- _trace(0),
- _dbEnv(0),
- _dbEnvHolder(SharedDbEnv::get(communicator, envName)),
- _dbName(dbName)
-{
- _dbEnv = _dbEnvHolder.get();
- openDb(createDb);
-}
-
-Freeze::DBMapHelperI::DBMapHelperI(const CommunicatorPtr& communicator,
- DbEnv& dbEnv,
- const string& dbName,
- bool createDb) :
- DBMapHelper(communicator),
- _trace(0),
- _dbEnv(&dbEnv),
- _dbName(dbName)
-{
- openDb(createDb);
-}
-
-void
-Freeze::DBMapHelperI::openDb(bool createDb)
-{
- _trace = _communicator->getProperties()->getPropertyAsInt("Freeze.Trace.DB");
-
- try
- {
- _db.reset(new Db(_dbEnv, 0));
- u_int32_t flags = DB_AUTO_COMMIT | DB_THREAD;
-
- if(createDb)
- {
- flags |= DB_CREATE;
- }
-
- if(_trace >= 2)
- {
- Trace out(_communicator->getLogger(), "DB");
- out << "opening database \"" << _dbName.c_str() << "\"";
- }
-
- _db->open(0, _dbName.c_str(), 0, DB_BTREE, flags, FREEZE_DB_MODE);
- }
- catch(const ::DbException& dx)
- {
- DBException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
+ _connection(connection),
+ _db(SharedDb::get(connection, dbName, createDb)),
+ _dbName(dbName),
+ _trace(connection->trace())
+{
+ _connection->registerMap(this);
}
-
Freeze::DBMapHelperI::~DBMapHelperI()
{
- if(_db.get() != 0)
- {
- try
- {
- if(_trace >= 2)
- {
- Trace out(_communicator->getLogger(), "DB");
- out << "closing database \"" << _dbName.c_str() << "\"";
- }
-
- _db->close(0);
- }
- catch(const ::DbException& dx)
- {
- DBException ex(__FILE__, __LINE__);
- ex.message = dx.what();
- throw ex;
- }
- _db.reset();
- }
- _dbEnvHolder = 0;
+ close();
}
Freeze::DBIteratorHelper*
@@ -784,9 +718,16 @@ Freeze::DBMapHelperI::find(const Key& k, bool readOnly) const
}
catch(const DBDeadlockException&)
{
- //
- // Ignored, try again
- //
+ if(_connection->dbTxn() != 0)
+ {
+ throw;
+ }
+ else
+ {
+ //
+ // Ignored, try again
+ //
+ }
}
}
}
@@ -799,11 +740,18 @@ Freeze::DBMapHelperI::put(const Key& key, const Value& value)
initializeInDbt(key, dbKey);
initializeInDbt(value, dbValue);
+ DbTxn* txn = _connection->dbTxn();
+ if(txn == 0)
+ {
+ closeAllIterators();
+ }
+
for(;;)
{
try
{
- int err = _db->put(0, &dbKey, &dbValue, DB_AUTO_COMMIT);
+ int err = _db->put(txn, &dbKey, &dbValue,
+ txn != 0 ? 0 : DB_AUTO_COMMIT);
if(err == 0)
{
@@ -817,11 +765,20 @@ Freeze::DBMapHelperI::put(const Key& key, const Value& value)
throw DBException(__FILE__, __LINE__);
}
}
- catch(const ::DbDeadlockException&)
+ catch(const ::DbDeadlockException& dx)
{
- //
- // Ignored, try again
- //
+ if(txn != 0)
+ {
+ DBDeadlockException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+ else
+ {
+ //
+ // Ignored, try again
+ //
+ }
}
catch(const ::DbException& dx)
{
@@ -838,11 +795,17 @@ Freeze::DBMapHelperI::erase(const Key& key)
Dbt dbKey;
initializeInDbt(key, dbKey);
+ DbTxn* txn = _connection->dbTxn();
+ if(txn == 0)
+ {
+ closeAllIterators();
+ }
+
for(;;)
{
try
{
- int err = _db->del(0, &dbKey, DB_AUTO_COMMIT);
+ int err = _db->del(txn, &dbKey, txn != 0 ? 0 : DB_AUTO_COMMIT);
if(err == 0)
{
@@ -858,11 +821,20 @@ Freeze::DBMapHelperI::erase(const Key& key)
throw DBException(__FILE__, __LINE__);
}
}
- catch(const ::DbDeadlockException&)
+ catch(const ::DbDeadlockException& dx)
{
- //
- // Ignored, try again
- //
+ if(txn != 0)
+ {
+ DBDeadlockException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+ else
+ {
+ //
+ // Ignored, try again
+ //
+ }
}
catch(const ::DbException& dx)
{
@@ -889,7 +861,7 @@ Freeze::DBMapHelperI::count(const Key& key) const
{
try
{
- int err = _db->get(0, &dbKey, &dbValue, 0);
+ int err = _db->get(_connection->dbTxn(), &dbKey, &dbValue, 0);
if(err == 0)
{
@@ -905,11 +877,20 @@ Freeze::DBMapHelperI::count(const Key& key) const
throw DBException(__FILE__, __LINE__);
}
}
- catch(const ::DbDeadlockException&)
+ catch(const ::DbDeadlockException& dx)
{
- //
- // Ignored, try again
- //
+ if(_connection->dbTxn() != 0)
+ {
+ DBDeadlockException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+ else
+ {
+ //
+ // Ignored, try again
+ //
+ }
}
catch(const ::DbException& dx)
{
@@ -923,20 +904,35 @@ Freeze::DBMapHelperI::count(const Key& key) const
void
Freeze::DBMapHelperI::clear()
{
+ DbTxn* txn = _connection->dbTxn();
+ if(txn == 0)
+ {
+ closeAllIterators();
+ }
+
for(;;)
{
try
{
u_int32_t count;
- int err = _db->truncate(0, &count, DB_AUTO_COMMIT);
+ int err = _db->truncate(txn, &count, txn != 0 ? 0 : DB_AUTO_COMMIT);
assert(err == 0);
break;
}
- catch(const ::DbDeadlockException&)
+ catch(const ::DbDeadlockException& dx)
{
- //
- // Ignored, try again
- //
+ if(txn != 0)
+ {
+ DBDeadlockException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+ else
+ {
+ //
+ // Ignored, try again
+ //
+ }
}
catch(const ::DbException& dx)
{
@@ -950,13 +946,16 @@ Freeze::DBMapHelperI::clear()
void
Freeze::DBMapHelperI::destroy()
{
- try
+ DbTxn* txn = _connection->dbTxn();
+ if(txn == 0)
{
- _db->close(0);
- _db.reset();
+ closeAllIterators();
+ }
- Db db(_dbEnv, 0);
- db.remove(_dbName.c_str(), 0, 0);
+ try
+ {
+ close();
+ _connection->dbEnv()->dbremove(txn, _dbName.c_str(), 0, txn != 0 ? 0 : DB_AUTO_COMMIT);
}
catch(const ::DbException& dx)
{
@@ -967,7 +966,6 @@ Freeze::DBMapHelperI::destroy()
}
-
size_t
Freeze::DBMapHelperI::size() const
{
@@ -983,6 +981,45 @@ Freeze::DBMapHelperI::size() const
}
+void
+Freeze::DBMapHelperI::closeAllIterators()
+{
+ while(!_iteratorList.empty())
+ {
+ (*_iteratorList.begin())->close();
+ }
+}
+
+void
+Freeze::DBMapHelperI::close()
+{
+ if(_db != 0)
+ {
+ _connection->unregisterMap(this);
+ }
+ _db = 0;
+}
+
+void
+Freeze::DBMapHelperI::closeAllIteratorsExcept(const DBIteratorHelperI::TxPtr& tx) const
+{
+ assert(tx != 0);
+
+ list<DBIteratorHelperI*>::iterator q = _iteratorList.begin();
+
+ while(q != _iteratorList.end())
+ {
+ if((*q)->tx().get() == tx.get())
+ {
+ ++q;
+ }
+ else
+ {
+ (*q)->close();
+ q = _iteratorList.begin();
+ }
+ }
+}
//
// Print for the various exception types.