Skip to content

Commit

Permalink
merge bitcoin#19308: BerkeleyBatch Handle cursor internally
Browse files Browse the repository at this point in the history
  • Loading branch information
kwvg committed Mar 5, 2022
1 parent d742934 commit 69ba10b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 35 deletions.
51 changes: 31 additions & 20 deletions src/wallet/bdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,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;
Expand Down Expand Up @@ -441,6 +441,7 @@ void BerkeleyBatch::Close()
activeTxn->abort();
activeTxn = nullptr;
pdb = nullptr;
CloseCursor();

if (fFlushOnClose)
Flush();
Expand Down Expand Up @@ -527,17 +528,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;
}
Expand All @@ -555,6 +554,8 @@ bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
if (ret2 > 0)
fSuccess = false;
}
db.CloseCursor();
}
if (fSuccess) {
db.Close();
env->CloseDb(strFile);
Expand Down Expand Up @@ -737,27 +738,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);
Expand All @@ -766,7 +770,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()
Expand Down
6 changes: 4 additions & 2 deletions src/wallet/bdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ class BerkeleyBatch
Db* pdb;
std::string strFile;
DbTxn* activeTxn;
Dbc* m_cursor;
bool fReadOnly;
bool fFlushOnClose;
BerkeleyEnvironment *env;
Expand Down Expand Up @@ -301,8 +302,9 @@ class BerkeleyBatch
return HasKey(ssKey);
}

Dbc* GetCursor();
int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue);
bool StartCursor();
bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete);
void CloseCursor();
bool TxnBegin();
bool TxnCommit();
bool TxnAbort();
Expand Down
28 changes: 15 additions & 13 deletions src/wallet/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
}

// Get cursor
Dbc* pcursor = m_batch.GetCursor();
if (!pcursor)
if (!m_batch.StartCursor())
{
pwallet->WalletLogPrintf("Error getting wallet database cursor\n");
return DBErrors::CORRUPT;
Expand All @@ -533,11 +532,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
bool complete;
bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
if (complete) {
break;
else if (ret != 0)
}
else if (!ret)
{
m_batch.CloseCursor();
pwallet->WalletLogPrintf("Error reading next record from wallet database\n");
return DBErrors::CORRUPT;
}
Expand All @@ -564,14 +566,14 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
if (!strErr.empty())
pwallet->WalletLogPrintf("%s\n", strErr);
}
pcursor->close();

// Store initial external keypool size since we mostly use external keys in mixing
pwallet->nKeysLeftSinceAutoBackup = pwallet->KeypoolCountExternalKeys();
pwallet->WalletLogPrintf("nKeysLeftSinceAutoBackup: %d\n", pwallet->nKeysLeftSinceAutoBackup);
} catch (...) {
result = DBErrors::CORRUPT;
}
m_batch.CloseCursor();

if (fNoncriticalErrors && result == DBErrors::LOAD_OK)
result = DBErrors::NONCRITICAL_ERROR;
Expand Down Expand Up @@ -632,8 +634,7 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CW
}

// Get cursor
Dbc* pcursor = m_batch.GetCursor();
if (!pcursor)
if (!m_batch.StartCursor())
{
LogPrintf("Error getting wallet database cursor\n");
return DBErrors::CORRUPT;
Expand All @@ -644,11 +645,12 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CW
// Read next record
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
if (ret == DB_NOTFOUND)
bool complete;
bool ret = m_batch.ReadAtCursor(ssKey, ssValue, complete);
if (complete) {
break;
else if (ret != 0)
{
} else if (!ret) {
m_batch.CloseCursor();
LogPrintf("Error reading next record from wallet database\n");
return DBErrors::CORRUPT;
}
Expand All @@ -666,10 +668,10 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CW
vWtx.push_back(wtx);
}
}
pcursor->close();
} catch (...) {
result = DBErrors::CORRUPT;
}
m_batch.CloseCursor();

return result;
}
Expand Down

0 comments on commit 69ba10b

Please sign in to comment.