summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Freeze/DBI.cpp196
-rw-r--r--cpp/src/Freeze/DBI.h18
2 files changed, 110 insertions, 104 deletions
diff --git a/cpp/src/Freeze/DBI.cpp b/cpp/src/Freeze/DBI.cpp
index 158b931460c..c1fc21b49f4 100644
--- a/cpp/src/Freeze/DBI.cpp
+++ b/cpp/src/Freeze/DBI.cpp
@@ -294,13 +294,10 @@ Freeze::DBTransactionI::abort()
_tid = 0;
}
-DBCursorI::DBCursorI(const ::Ice::CommunicatorPtr& communicator, const std::string& name, DBC* cursor,
- bool hasCurrentValue) :
+DBCursorI::DBCursorI(const ::Ice::CommunicatorPtr& communicator, const std::string& name, DBC* cursor) :
_communicator(communicator),
_trace(0),
_name(name),
- _canRemove(false),
- _hasCurrentValue(hasCurrentValue),
_cursor(cursor)
{
PropertiesPtr properties = _communicator->getProperties();
@@ -339,8 +336,42 @@ DBCursorI::getCommunicator()
return _communicator;
}
+void
+DBCursorI::curr(Key& key, Value& value)
+{
+ JTCSyncT<JTCMutex> sync(*this);
+
+ if (!_cursor)
+ {
+ ostringstream s;
+ s << _errorPrefix << "\"" << _name << "\" has been closed";
+ DBException ex;
+ ex.message = s.str();
+ throw ex;
+ }
+
+ DBT dbKey, dbData;
+ memset(&dbKey, 0, sizeof(dbKey));
+ memset(&dbData, 0, sizeof(dbData));
+
+ if (_trace >= 1)
+ {
+ ostringstream s;
+ s << "reading current value from database \"" << _name << "\"";
+ _communicator->getLogger()->trace("DBCursor", s.str());
+ }
+
+ checkBerkeleyDBReturn(_cursor->c_get(_cursor, &dbKey, &dbData, DB_CURRENT), _errorPrefix, "DBcursor->c_get");
+
+ //
+ // Copy the data from the read key & data
+ //
+ key = Key(static_cast<Byte*>(dbKey.data), static_cast<Byte*>(dbKey.data) + dbKey.size);
+ value = Value(static_cast<Byte*>(dbData.data), static_cast<Byte*>(dbData.data) + dbData.size);
+}
+
bool
-DBCursorI::hasNext()
+DBCursorI::next()
{
JTCSyncT<JTCMutex> sync(*this);
@@ -354,62 +385,35 @@ DBCursorI::hasNext()
}
//
- // Note that the reads are partial reads since this method only
- // verifies that there is a next value
+ // This does a 0 byte partial read of the data for efficiency
+ // reasons.
//
DBT dbKey, dbData;
memset(&dbKey, 0, sizeof(dbKey));
dbKey.flags = DB_DBT_PARTIAL;
-
memset(&dbData, 0, sizeof(dbData));
dbData.flags = DB_DBT_PARTIAL;
- //
- // If we've already verified that there is a next record then
- // verify that the current record still exists.
- //
- if (_hasCurrentValue)
+ if (_trace >= 1)
{
- try
- {
- checkBerkeleyDBReturn(_cursor->c_get(_cursor, &dbKey, &dbData, DB_CURRENT), _errorPrefix,
- "DBcursor->c_get");\
- }
- catch(const DBNotFoundException&)
- {
- //
- // There is no next record.
- //
- return false;
- }
- return true;
+ ostringstream s;
+ s << "moving to next value in database \"" << _name << "\"";
+ _communicator->getLogger()->trace("DBCursor", s.str());
}
- //
- // Otherwise, move to the next record.
- //
try
{
- checkBerkeleyDBReturn(_cursor->c_get(_cursor, &dbKey, &dbData, DB_NEXT), _errorPrefix,
- "DBcursor->c_get");\
+ checkBerkeleyDBReturn(_cursor->c_get(_cursor, &dbKey, &dbData, DB_NEXT), _errorPrefix, "DBcursor->c_get");
}
catch(const DBNotFoundException&)
{
- //
- // There is no next record
- //
return false;
}
-
- //
- // We now have a current value.
- //
- _hasCurrentValue = true;
return true;
}
-void
-DBCursorI::next(Key& key, Value& value)
+bool
+DBCursorI::prev()
{
JTCSyncT<JTCMutex> sync(*this);
@@ -422,48 +426,36 @@ DBCursorI::next(Key& key, Value& value)
throw ex;
}
+ //
+ // This does a 0 byte partial read of the data for efficiency
+ // reasons.
+ //
DBT dbKey, dbData;
memset(&dbKey, 0, sizeof(dbKey));
+ dbKey.flags = DB_DBT_PARTIAL;
memset(&dbData, 0, sizeof(dbData));
+ dbData.flags = DB_DBT_PARTIAL;
- u_int32_t getFlags;
- string desc;
-
- //
- // Do we need to move to the next record?
- //
- if (!_hasCurrentValue)
+ if (_trace >= 1)
{
- getFlags = DB_NEXT;
- desc = "next";
+ ostringstream s;
+ s << "moving to previous value in database \"" << _name << "\"";
+ _communicator->getLogger()->trace("DBCursor", s.str());
}
- else
+
+ try
{
- getFlags = DB_CURRENT;
- desc = "current";
+ checkBerkeleyDBReturn(_cursor->c_get(_cursor, &dbKey, &dbData, DB_PREV), _errorPrefix, "DBcursor->c_get");
}
-
- if (_trace >= 1)
+ catch(const DBNotFoundException&)
{
- ostringstream s;
- s << "reading " << desc << " value from database \"" << _name << "\"";
- _communicator->getLogger()->trace("DB", s.str());
+ return false;
}
-
- checkBerkeleyDBReturn(_cursor->c_get(_cursor, &dbKey, &dbData, getFlags), _errorPrefix, "DBcursor->c_get");
-
- //
- // Copy the data from the read key & data
- //
- key = Key(static_cast<Byte*>(dbKey.data), static_cast<Byte*>(dbKey.data) + dbKey.size);
- value = Value(static_cast<Byte*>(dbData.data), static_cast<Byte*>(dbData.data) + dbData.size);
-
- _canRemove = true;
- _hasCurrentValue = false;
+ return true;
}
void
-DBCursorI::remove()
+DBCursorI::del()
{
JTCSyncT<JTCMutex> sync(*this);
@@ -476,25 +468,14 @@ DBCursorI::remove()
throw ex;
}
- if (!_canRemove)
- {
- DBNotFoundException ex;
- ex.message = "The next method has not yet been called, or the remove method has already been called "
- "after the last call to the next method.";
- throw ex;
- }
-
if (_trace >= 1)
{
ostringstream s;
- s << "deleting value from database \"" << _name << "\"";
- _communicator->getLogger()->trace("DB", s.str());
+ s << "removing the current element in database \"" << _name << "\"";
+ _communicator->getLogger()->trace("DBCursor", s.str());
}
- checkBerkeleyDBReturn( _cursor->c_del(_cursor, 0), _errorPrefix, "DBcursor->c_del");
-
- _hasCurrentValue = false;
- _canRemove = false;
+ checkBerkeleyDBReturn(_cursor->c_del(_cursor, 0), _errorPrefix, "DBcursor->c_del");
}
DBCursorPtr
@@ -513,7 +494,7 @@ DBCursorI::clone()
DBC* cursor;
_cursor->c_dup(_cursor, &cursor, DB_POSITION);
- return new DBCursorI(_communicator, _name, cursor, _hasCurrentValue);
+ return new DBCursorI(_communicator, _name, cursor);
}
void
@@ -594,7 +575,7 @@ Freeze::DBI::getCommunicator()
}
Long
-Freeze::DBI::getNumberRecords()
+Freeze::DBI::getNumberOfRecords()
{
JTCSyncT<JTCMutex> sync(*this);
@@ -607,11 +588,14 @@ Freeze::DBI::getNumberRecords()
throw ex;
}
- DB_BTREE_STAT s;
-
- checkBerkeleyDBReturn(_db->stat(_db, &s, DB_FAST_STAT), _errorPrefix, "DB->stat");
-
- return s.bt_ndata;
+ //
+ // TODO: DB_FAST_STAT doesn't seem to do what the documentation says...
+ //
+ DB_BTREE_STAT* s;
+ checkBerkeleyDBReturn(_db->stat(_db, &s, 0), _errorPrefix, "DB->stat");
+ Long num = s->bt_ndata;
+ free(s);
+ return num;
}
DBCursorPtr
@@ -632,11 +616,35 @@ Freeze::DBI::getCursor()
checkBerkeleyDBReturn(_db->cursor(_db, 0, &cursor, 0), _errorPrefix, "DB->cursor");
- return new DBCursorI(_communicator, _name, cursor, false);
+ //
+ // Note that the read of the data is partial (that is the data
+ // will not actually be read into memory since it isn't needed
+ // yet).
+ //
+ DBT dbData, dbKey;
+ memset(&dbData, 0, sizeof(dbData));
+ dbData.flags = DB_DBT_PARTIAL;
+ memset(&dbKey, 0, sizeof(dbKey));
+ dbKey.flags = DB_DBT_PARTIAL;
+
+ try
+ {
+ checkBerkeleyDBReturn(cursor->c_get(cursor, &dbKey, &dbData, DB_FIRST), _errorPrefix, "DBcursor->c_get");
+ }
+ catch(const DBNotFoundException&)
+ {
+ //
+ // Cleanup.
+ //
+ cursor->c_close(cursor);
+ throw;
+ }
+
+ return new DBCursorI(_communicator, _name, cursor);
}
DBCursorPtr
-Freeze::DBI::getCursorForKey(const Key& key)
+Freeze::DBI::getCursorAtKey(const Key& key)
{
JTCSyncT<JTCMutex> sync(*this);
@@ -683,7 +691,7 @@ Freeze::DBI::getCursorForKey(const Key& key)
throw;
}
- return new DBCursorI(_communicator, _name, cursor, true);
+ return new DBCursorI(_communicator, _name, cursor);
}
void
diff --git a/cpp/src/Freeze/DBI.h b/cpp/src/Freeze/DBI.h
index fa116d7af2b..3265d6ad6a4 100644
--- a/cpp/src/Freeze/DBI.h
+++ b/cpp/src/Freeze/DBI.h
@@ -87,15 +87,16 @@ class DBCursorI : public DBCursor, public JTCMutex
{
public:
- DBCursorI(const ::Ice::CommunicatorPtr&, const std::string&, DBC*, bool);
+ DBCursorI(const ::Ice::CommunicatorPtr&, const std::string&, DBC*);
~DBCursorI();
virtual ::Ice::CommunicatorPtr getCommunicator();
- virtual bool hasNext();
- virtual void next(Key& key, Value& value);
- virtual void remove();
-
+ virtual void curr(Key& key, Value& value);
+ virtual bool next();
+ virtual bool prev();
+ virtual void del();
+
virtual DBCursorPtr clone();
virtual void close();
@@ -107,9 +108,6 @@ private:
std::string _name;
std::string _errorPrefix;
- bool _canRemove; // Can remove be called?
- bool _hasCurrentValue; // Have we already verified that there is a next value?
-
DBC* _cursor;
};
@@ -123,10 +121,10 @@ public:
virtual std::string getName();
virtual ::Ice::CommunicatorPtr getCommunicator();
- virtual ::Ice::Long getNumberRecords();
+ virtual ::Ice::Long getNumberOfRecords();
virtual DBCursorPtr getCursor();
- virtual DBCursorPtr getCursorForKey(const Key&);
+ virtual DBCursorPtr getCursorAtKey(const Key&);
virtual void put(const Key&, const Value&);
virtual Value get(const Key&);