Skip to content

Commit ca24edf

Browse files
committed
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.
1 parent 39bd9dd commit ca24edf

File tree

3 files changed

+50
-35
lines changed

3 files changed

+50
-35
lines changed

src/wallet/bdb.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile)
335335
}
336336

337337

338-
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr)
338+
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr)
339339
{
340340
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
341341
fFlushOnClose = fFlushOnCloseIn;
@@ -442,6 +442,7 @@ void BerkeleyBatch::Close()
442442
activeTxn->abort();
443443
activeTxn = nullptr;
444444
pdb = nullptr;
445+
CloseCursor();
445446

446447
if (fFlushOnClose)
447448
Flush();
@@ -528,17 +529,15 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
528529
fSuccess = false;
529530
}
530531

531-
Dbc* pcursor = db.GetCursor();
532-
if (pcursor)
532+
if (db.StartCursor()) {
533533
while (fSuccess) {
534534
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
535535
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
536-
int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue);
537-
if (ret1 == DB_NOTFOUND) {
538-
pcursor->close();
536+
bool complete;
537+
bool ret1 = db.ReadAtCursor(ssKey, ssValue, complete);
538+
if (complete) {
539539
break;
540-
} else if (ret1 != 0) {
541-
pcursor->close();
540+
} else if (!ret1) {
542541
fSuccess = false;
543542
break;
544543
}
@@ -556,6 +555,8 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
556555
if (ret2 > 0)
557556
fSuccess = false;
558557
}
558+
db.CloseCursor();
559+
}
559560
if (fSuccess) {
560561
db.Close();
561562
env->CloseDb(strFile);
@@ -738,27 +739,30 @@ void BerkeleyDatabase::ReloadDbEnv()
738739
}
739740
}
740741

741-
Dbc* BerkeleyBatch::GetCursor()
742+
bool BerkeleyBatch::StartCursor()
742743
{
744+
assert(!m_cursor);
743745
if (!pdb)
744-
return nullptr;
745-
Dbc* pcursor = nullptr;
746-
int ret = pdb->cursor(nullptr, &pcursor, 0);
747-
if (ret != 0)
748-
return nullptr;
749-
return pcursor;
746+
return false;
747+
int ret = pdb->cursor(nullptr, &m_cursor, 0);
748+
return ret == 0;
750749
}
751750

752-
int BerkeleyBatch::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue)
751+
bool BerkeleyBatch::ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete)
753752
{
753+
complete = false;
754+
if (m_cursor == nullptr) return false;
754755
// Read at cursor
755756
SafeDbt datKey;
756757
SafeDbt datValue;
757-
int ret = pcursor->get(datKey, datValue, DB_NEXT);
758+
int ret = m_cursor->get(datKey, datValue, DB_NEXT);
759+
if (ret == DB_NOTFOUND) {
760+
complete = true;
761+
}
758762
if (ret != 0)
759-
return ret;
763+
return false;
760764
else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr)
761-
return 99999;
765+
return false;
762766

763767
// Convert to streams
764768
ssKey.SetType(SER_DISK);
@@ -767,7 +771,14 @@ int BerkeleyBatch::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& s
767771
ssValue.SetType(SER_DISK);
768772
ssValue.clear();
769773
ssValue.write((char*)datValue.get_data(), datValue.get_size());
770-
return 0;
774+
return true;
775+
}
776+
777+
void BerkeleyBatch::CloseCursor()
778+
{
779+
if (!m_cursor) return;
780+
m_cursor->close();
781+
m_cursor = nullptr;
771782
}
772783

773784
bool BerkeleyBatch::TxnBegin()

src/wallet/bdb.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class BerkeleyBatch
211211
Db* pdb;
212212
std::string strFile;
213213
DbTxn* activeTxn;
214+
Dbc* m_cursor;
214215
bool fReadOnly;
215216
bool fFlushOnClose;
216217
BerkeleyEnvironment *env;
@@ -323,8 +324,9 @@ class BerkeleyBatch
323324
return (ret == 0);
324325
}
325326

326-
Dbc* GetCursor();
327-
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue);
327+
bool StartCursor();
328+
bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete);
329+
void CloseCursor();
328330
bool TxnBegin();
329331
bool TxnCommit();
330332
bool TxnAbort();

src/wallet/walletdb.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -699,8 +699,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
699699
}
700700

701701
// Get cursor
702-
Dbc* pcursor = m_batch.GetCursor();
703-
if (!pcursor)
702+
if (!m_batch.StartCursor())
704703
{
705704
pwallet->WalletLogPrintf("Error getting wallet database cursor\n");
706705
return DBErrors::CORRUPT;
@@ -711,11 +710,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
711710
// Read next record
712711
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
713712
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
714-
int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
715-
if (ret == DB_NOTFOUND)
713+
bool complete;
714+
bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
715+
if (complete) {
716716
break;
717-
else if (ret != 0)
717+
}
718+
else if (!ret)
718719
{
720+
m_batch.CloseCursor();
719721
pwallet->WalletLogPrintf("Error reading next record from wallet database\n");
720722
return DBErrors::CORRUPT;
721723
}
@@ -742,10 +744,10 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
742744
if (!strErr.empty())
743745
pwallet->WalletLogPrintf("%s\n", strErr);
744746
}
745-
pcursor->close();
746747
} catch (...) {
747748
result = DBErrors::CORRUPT;
748749
}
750+
m_batch.CloseCursor();
749751

750752
// Set the active ScriptPubKeyMans
751753
for (auto spk_man_pair : wss.m_active_external_spks) {
@@ -849,8 +851,7 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
849851
}
850852

851853
// Get cursor
852-
Dbc* pcursor = m_batch.GetCursor();
853-
if (!pcursor)
854+
if (!m_batch.StartCursor())
854855
{
855856
LogPrintf("Error getting wallet database cursor\n");
856857
return DBErrors::CORRUPT;
@@ -861,11 +862,12 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
861862
// Read next record
862863
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
863864
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
864-
int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
865-
if (ret == DB_NOTFOUND)
865+
bool complete;
866+
bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
867+
if (complete) {
866868
break;
867-
else if (ret != 0)
868-
{
869+
} else if (!ret) {
870+
m_batch.CloseCursor();
869871
LogPrintf("Error reading next record from wallet database\n");
870872
return DBErrors::CORRUPT;
871873
}
@@ -880,10 +882,10 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
880882
ssValue >> vWtx.back();
881883
}
882884
}
883-
pcursor->close();
884885
} catch (...) {
885886
result = DBErrors::CORRUPT;
886887
}
888+
m_batch.CloseCursor();
887889

888890
return result;
889891
}

0 commit comments

Comments
 (0)