aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/bdb.cpp
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2020-05-14 21:17:01 -0400
committerAndrew Chow <achow101-github@achow101.com>2020-06-22 15:36:23 -0400
commitca24edfbc1941ed0a3c9586416dae4e84794eb66 (patch)
tree1cd6eb3d10bb421f399d98df1c7a4340afb1a59c /src/wallet/bdb.cpp
parent39bd9ddb8783807b9cde6288233e86ad7c85d61f (diff)
downloadbitcoin-ca24edfbc1941ed0a3c9586416dae4e84794eb66.tar.xz
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.
Diffstat (limited to 'src/wallet/bdb.cpp')
-rw-r--r--src/wallet/bdb.cpp51
1 files changed, 31 insertions, 20 deletions
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 7ed9c88122..eb62d6664e 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -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()