Skip to content

Commit

Permalink
Merge c7ebab1 into merged_master (Bitcoin PR #19292)
Browse files Browse the repository at this point in the history
  • Loading branch information
apoelstra committed Nov 26, 2020
2 parents 2468108 + c7ebab1 commit 888295e
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 33 deletions.
64 changes: 64 additions & 0 deletions src/wallet/bdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,3 +803,67 @@ std::string BerkeleyDatabaseVersion()
{
return DbEnv::version(nullptr, nullptr, nullptr);
}

bool BerkeleyBatch::ReadKey(CDataStream& key, CDataStream& value)
{
if (!pdb)
return false;

// Key
SafeDbt datKey(key.data(), key.size());

// Read
SafeDbt datValue;
int ret = pdb->get(activeTxn, datKey, datValue, 0);
if (ret == 0 && datValue.get_data() != nullptr) {
value.write((char*)datValue.get_data(), datValue.get_size());
return true;
}
return false;
}

bool BerkeleyBatch::WriteKey(CDataStream& key, CDataStream& value, bool overwrite)
{
if (!pdb)
return true;
if (fReadOnly)
assert(!"Write called on database in read-only mode");

// Key
SafeDbt datKey(key.data(), key.size());

// Value
SafeDbt datValue(value.data(), value.size());

// Write
int ret = pdb->put(activeTxn, datKey, datValue, (overwrite ? 0 : DB_NOOVERWRITE));
return (ret == 0);
}

bool BerkeleyBatch::EraseKey(CDataStream& key)
{
if (!pdb)
return false;
if (fReadOnly)
assert(!"Erase called on database in read-only mode");

// Key
SafeDbt datKey(key.data(), key.size());

// Erase
int ret = pdb->del(activeTxn, datKey, 0);
return (ret == 0 || ret == DB_NOTFOUND);
}

bool BerkeleyBatch::HasKey(CDataStream& key)
{
if (!pdb)
return false;

// Key
SafeDbt datKey(key.data(), key.size());

// Exists
int ret = pdb->exists(activeTxn, datKey, 0);
return ret == 0;
}
46 changes: 13 additions & 33 deletions src/wallet/bdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ class BerkeleyBatch
operator Dbt*();
};

private:
bool ReadKey(CDataStream& key, CDataStream& value);
bool WriteKey(CDataStream& key, CDataStream& value, bool overwrite=true);
bool EraseKey(CDataStream& key);
bool HasKey(CDataStream& key);

protected:
Db* pdb;
std::string strFile;
Expand Down Expand Up @@ -236,91 +242,65 @@ class BerkeleyBatch
template <typename K, typename T>
bool Read(const K& key, T& value)
{
if (!pdb)
return false;

// Key
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
SafeDbt datKey(ssKey.data(), ssKey.size());

// Read
SafeDbt datValue;
int ret = pdb->get(activeTxn, datKey, datValue, 0);
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
bool success = false;
if (datValue.get_data() != nullptr) {
bool ret = ReadKey(ssKey, ssValue);
if (ret) {
// Unserialize value
try {
CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
ssValue >> value;
success = true;
} catch (const std::exception&) {
// In this case success remains 'false'
}
}
return ret == 0 && success;
return ret && success;
}

template <typename K, typename T>
bool Write(const K& key, const T& value, bool fOverwrite = true)
{
if (!pdb)
return true;
if (fReadOnly)
assert(!"Write called on database in read-only mode");

// Key
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
SafeDbt datKey(ssKey.data(), ssKey.size());

// Value
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
ssValue.reserve(10000);
ssValue << value;
SafeDbt datValue(ssValue.data(), ssValue.size());

// Write
int ret = pdb->put(activeTxn, datKey, datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
return (ret == 0);
return WriteKey(ssKey, ssValue, fOverwrite);
}

template <typename K>
bool Erase(const K& key)
{
if (!pdb)
return false;
if (fReadOnly)
assert(!"Erase called on database in read-only mode");

// Key
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
SafeDbt datKey(ssKey.data(), ssKey.size());

// Erase
int ret = pdb->del(activeTxn, datKey, 0);
return (ret == 0 || ret == DB_NOTFOUND);
return EraseKey(ssKey);
}

template <typename K>
bool Exists(const K& key)
{
if (!pdb)
return false;

// Key
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
SafeDbt datKey(ssKey.data(), ssKey.size());

// Exists
int ret = pdb->exists(activeTxn, datKey, 0);
return (ret == 0);
return HasKey(ssKey);
}

Dbc* GetCursor();
Expand Down

0 comments on commit 888295e

Please sign in to comment.