Skip to content

Commit 2629174

Browse files
committed
Merge #19308: wallet: BerkeleyBatch Handle cursor internally
ca24edf walletdb: Handle cursor internally (Andrew Chow) Pull request description: Instead of returning a Dbc (BDB cursor object) and having the caller deal with the cursor, make BerkeleyBatch handle the cursor internally. Split from #18971 ACKs for top commit: ryanofsky: Code review ACK ca24edf. Changes since last review: StartCursor rename, moving CloseCursor calls near returns promag: Code review ACK ca24edf. Tree-SHA512: f029b498c7f275aedca53ce7ade7cb99c82975fd6cad17346a4990fb3bcc54e2a5309b32053bd13def9ee464d331b036ac79abb8fc4fa561170c6cfc85283447
2 parents bb58866 + ca24edf commit 2629174

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
@@ -198,6 +198,7 @@ class BerkeleyBatch
198198
Db* pdb;
199199
std::string strFile;
200200
DbTxn* activeTxn;
201+
Dbc* m_cursor;
201202
bool fReadOnly;
202203
bool fFlushOnClose;
203204
BerkeleyEnvironment *env;
@@ -284,8 +285,9 @@ class BerkeleyBatch
284285
return HasKey(ssKey);
285286
}
286287

287-
Dbc* GetCursor();
288-
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue);
288+
bool StartCursor();
289+
bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete);
290+
void CloseCursor();
289291
bool TxnBegin();
290292
bool TxnCommit();
291293
bool TxnAbort();

src/wallet/walletdb.cpp

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

702702
// Get cursor
703-
Dbc* pcursor = m_batch.GetCursor();
704-
if (!pcursor)
703+
if (!m_batch.StartCursor())
705704
{
706705
pwallet->WalletLogPrintf("Error getting wallet database cursor\n");
707706
return DBErrors::CORRUPT;
@@ -712,11 +711,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
712711
// Read next record
713712
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
714713
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
715-
int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
716-
if (ret == DB_NOTFOUND)
714+
bool complete;
715+
bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
716+
if (complete) {
717717
break;
718-
else if (ret != 0)
718+
}
719+
else if (!ret)
719720
{
721+
m_batch.CloseCursor();
720722
pwallet->WalletLogPrintf("Error reading next record from wallet database\n");
721723
return DBErrors::CORRUPT;
722724
}
@@ -743,10 +745,10 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
743745
if (!strErr.empty())
744746
pwallet->WalletLogPrintf("%s\n", strErr);
745747
}
746-
pcursor->close();
747748
} catch (...) {
748749
result = DBErrors::CORRUPT;
749750
}
751+
m_batch.CloseCursor();
750752

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

852854
// Get cursor
853-
Dbc* pcursor = m_batch.GetCursor();
854-
if (!pcursor)
855+
if (!m_batch.StartCursor())
855856
{
856857
LogPrintf("Error getting wallet database cursor\n");
857858
return DBErrors::CORRUPT;
@@ -862,11 +863,12 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
862863
// Read next record
863864
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
864865
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
865-
int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
866-
if (ret == DB_NOTFOUND)
866+
bool complete;
867+
bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
868+
if (complete) {
867869
break;
868-
else if (ret != 0)
869-
{
870+
} else if (!ret) {
871+
m_batch.CloseCursor();
870872
LogPrintf("Error reading next record from wallet database\n");
871873
return DBErrors::CORRUPT;
872874
}
@@ -881,10 +883,10 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
881883
ssValue >> vWtx.back();
882884
}
883885
}
884-
pcursor->close();
885886
} catch (...) {
886887
result = DBErrors::CORRUPT;
887888
}
889+
m_batch.CloseCursor();
888890

889891
return result;
890892
}

0 commit comments

Comments
 (0)