mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-26 14:00:29 +01:00
walletdb: Handle cursor internally
Instead of returning a Dbc (BDB cursor object) and having the caller deal with the cursor, make BerkeleyBatch handle the cursor internally. This prepares BerkeleyBatch to work with other database systems as Dbc objects are BDB specific.
This commit is contained in:
@@ -335,7 +335,7 @@ void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile)
|
||||
}
|
||||
|
||||
|
||||
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr)
|
||||
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr)
|
||||
{
|
||||
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
||||
fFlushOnClose = fFlushOnCloseIn;
|
||||
@@ -442,6 +442,7 @@ void BerkeleyBatch::Close()
|
||||
activeTxn->abort();
|
||||
activeTxn = nullptr;
|
||||
pdb = nullptr;
|
||||
CloseCursor();
|
||||
|
||||
if (fFlushOnClose)
|
||||
Flush();
|
||||
@@ -528,17 +529,15 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
|
||||
fSuccess = false;
|
||||
}
|
||||
|
||||
Dbc* pcursor = db.GetCursor();
|
||||
if (pcursor)
|
||||
if (db.StartCursor()) {
|
||||
while (fSuccess) {
|
||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
|
||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
|
||||
int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue);
|
||||
if (ret1 == DB_NOTFOUND) {
|
||||
pcursor->close();
|
||||
bool complete;
|
||||
bool ret1 = db.ReadAtCursor(ssKey, ssValue, complete);
|
||||
if (complete) {
|
||||
break;
|
||||
} else if (ret1 != 0) {
|
||||
pcursor->close();
|
||||
} else if (!ret1) {
|
||||
fSuccess = false;
|
||||
break;
|
||||
}
|
||||
@@ -556,6 +555,8 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
|
||||
if (ret2 > 0)
|
||||
fSuccess = false;
|
||||
}
|
||||
db.CloseCursor();
|
||||
}
|
||||
if (fSuccess) {
|
||||
db.Close();
|
||||
env->CloseDb(strFile);
|
||||
@@ -738,27 +739,30 @@ void BerkeleyDatabase::ReloadDbEnv()
|
||||
}
|
||||
}
|
||||
|
||||
Dbc* BerkeleyBatch::GetCursor()
|
||||
bool BerkeleyBatch::StartCursor()
|
||||
{
|
||||
assert(!m_cursor);
|
||||
if (!pdb)
|
||||
return nullptr;
|
||||
Dbc* pcursor = nullptr;
|
||||
int ret = pdb->cursor(nullptr, &pcursor, 0);
|
||||
if (ret != 0)
|
||||
return nullptr;
|
||||
return pcursor;
|
||||
return false;
|
||||
int ret = pdb->cursor(nullptr, &m_cursor, 0);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
int BerkeleyBatch::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue)
|
||||
bool BerkeleyBatch::ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete)
|
||||
{
|
||||
complete = false;
|
||||
if (m_cursor == nullptr) return false;
|
||||
// Read at cursor
|
||||
SafeDbt datKey;
|
||||
SafeDbt datValue;
|
||||
int ret = pcursor->get(datKey, datValue, DB_NEXT);
|
||||
int ret = m_cursor->get(datKey, datValue, DB_NEXT);
|
||||
if (ret == DB_NOTFOUND) {
|
||||
complete = true;
|
||||
}
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return false;
|
||||
else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr)
|
||||
return 99999;
|
||||
return false;
|
||||
|
||||
// Convert to streams
|
||||
ssKey.SetType(SER_DISK);
|
||||
@@ -767,7 +771,14 @@ int BerkeleyBatch::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& s
|
||||
ssValue.SetType(SER_DISK);
|
||||
ssValue.clear();
|
||||
ssValue.write((char*)datValue.get_data(), datValue.get_size());
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BerkeleyBatch::CloseCursor()
|
||||
{
|
||||
if (!m_cursor) return;
|
||||
m_cursor->close();
|
||||
m_cursor = nullptr;
|
||||
}
|
||||
|
||||
bool BerkeleyBatch::TxnBegin()
|
||||
|
||||
Reference in New Issue
Block a user