mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-03 09:43:55 +02:00
wallet: Add DatabaseBatch::ErasePrefix method
This new function is not used yet this commit, but next commit adds usages and test coverage for both BDB and sqlite.
This commit is contained in:
@@ -665,12 +665,14 @@ void BerkeleyDatabase::ReloadDbEnv()
|
||||
env->ReloadDbEnv();
|
||||
}
|
||||
|
||||
BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database)
|
||||
BerkeleyCursor::BerkeleyCursor(BerkeleyDatabase& database, BerkeleyBatch* batch)
|
||||
{
|
||||
if (!database.m_db.get()) {
|
||||
throw std::runtime_error(STR_INTERNAL_BUG("BerkeleyDatabase does not exist"));
|
||||
}
|
||||
int ret = database.m_db->cursor(nullptr, &m_cursor, 0);
|
||||
// Transaction argument to cursor is only needed when using the cursor to
|
||||
// write to the database. Read-only cursors do not need a txn pointer.
|
||||
int ret = database.m_db->cursor(batch ? batch->txn() : nullptr, &m_cursor, 0);
|
||||
if (ret != 0) {
|
||||
throw std::runtime_error(STR_INTERNAL_BUG(strprintf("BDB Cursor could not be created. Returned %d", ret)));
|
||||
}
|
||||
@@ -817,6 +819,25 @@ bool BerkeleyBatch::HasKey(DataStream&& key)
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
bool BerkeleyBatch::ErasePrefix(Span<const std::byte> prefix)
|
||||
{
|
||||
if (!TxnBegin()) return false;
|
||||
auto cursor{std::make_unique<BerkeleyCursor>(m_database, this)};
|
||||
// const_cast is safe below even though prefix_key is an in/out parameter,
|
||||
// because we are not using the DB_DBT_USERMEM flag, so BDB will allocate
|
||||
// and return a different output data pointer
|
||||
Dbt prefix_key{const_cast<std::byte*>(prefix.data()), static_cast<uint32_t>(prefix.size())}, prefix_value{};
|
||||
int ret{cursor->dbc()->get(&prefix_key, &prefix_value, DB_SET_RANGE)};
|
||||
for (int flag{DB_CURRENT}; ret == 0; flag = DB_NEXT) {
|
||||
SafeDbt key, value;
|
||||
ret = cursor->dbc()->get(key, value, flag);
|
||||
if (ret != 0 || key.get_size() < prefix.size() || memcmp(key.get_data(), prefix.data(), prefix.size()) != 0) break;
|
||||
ret = cursor->dbc()->del(0);
|
||||
}
|
||||
cursor.reset();
|
||||
return TxnCommit() && (ret == 0 || ret == DB_NOTFOUND);
|
||||
}
|
||||
|
||||
void BerkeleyDatabase::AddRef()
|
||||
{
|
||||
LOCK(cs_db);
|
||||
|
||||
Reference in New Issue
Block a user