refactor: Move CDBWrapper leveldb members to their own context struct

The context of this commit is an effort to decouple the dbwrapper header
file from leveldb includes. To this end, the includes are moved to the
dbwrapper implementation file. This is done as part of the kernel
project to reduce the number of required includes for users of the
kernel.
pull/28186/head
TheCharlatan 1 year ago
parent c534a615e9
commit c95b37d641
No known key found for this signature in database
GPG Key ID: 9B79B45691DB4173

@ -196,23 +196,46 @@ void CDBBatch::EraseImpl(Span<const std::byte> ssKey)
size_estimate += 2 + (slKey.size() > 127) + slKey.size();
}
struct LevelDBContext {
//! custom environment this database is using (may be nullptr in case of default environment)
leveldb::Env* penv;
//! database options used
leveldb::Options options;
//! options used when reading from the database
leveldb::ReadOptions readoptions;
//! options used when iterating over values of the database
leveldb::ReadOptions iteroptions;
//! options used when writing to the database
leveldb::WriteOptions writeoptions;
//! options used when sync writing to the database
leveldb::WriteOptions syncoptions;
//! the database itself
leveldb::DB* pdb;
};
CDBWrapper::CDBWrapper(const DBParams& params)
: m_name{fs::PathToString(params.path.stem())}, m_path{params.path}, m_is_memory{params.memory_only}
: m_db_context{std::make_unique<LevelDBContext>()}, m_name{fs::PathToString(params.path.stem())}, m_path{params.path}, m_is_memory{params.memory_only}
{
penv = nullptr;
readoptions.verify_checksums = true;
iteroptions.verify_checksums = true;
iteroptions.fill_cache = false;
syncoptions.sync = true;
options = GetOptions(params.cache_bytes);
options.create_if_missing = true;
DBContext().penv = nullptr;
DBContext().readoptions.verify_checksums = true;
DBContext().iteroptions.verify_checksums = true;
DBContext().iteroptions.fill_cache = false;
DBContext().syncoptions.sync = true;
DBContext().options = GetOptions(params.cache_bytes);
DBContext().options.create_if_missing = true;
if (params.memory_only) {
penv = leveldb::NewMemEnv(leveldb::Env::Default());
options.env = penv;
DBContext().penv = leveldb::NewMemEnv(leveldb::Env::Default());
DBContext().options.env = DBContext().penv;
} else {
if (params.wipe_data) {
LogPrintf("Wiping LevelDB in %s\n", fs::PathToString(params.path));
leveldb::Status result = leveldb::DestroyDB(fs::PathToString(params.path), options);
leveldb::Status result = leveldb::DestroyDB(fs::PathToString(params.path), DBContext().options);
HandleError(result);
}
TryCreateDirectories(params.path);
@ -222,13 +245,13 @@ CDBWrapper::CDBWrapper(const DBParams& params)
// because on POSIX leveldb passes the byte string directly to ::open(), and
// on Windows it converts from UTF-8 to UTF-16 before calling ::CreateFileW
// (see env_posix.cc and env_windows.cc).
leveldb::Status status = leveldb::DB::Open(options, fs::PathToString(params.path), &pdb);
leveldb::Status status = leveldb::DB::Open(DBContext().options, fs::PathToString(params.path), &DBContext().pdb);
HandleError(status);
LogPrintf("Opened LevelDB successfully\n");
if (params.options.force_compact) {
LogPrintf("Starting database compaction of %s\n", fs::PathToString(params.path));
pdb->CompactRange(nullptr, nullptr);
DBContext().pdb->CompactRange(nullptr, nullptr);
LogPrintf("Finished database compaction of %s\n", fs::PathToString(params.path));
}
@ -254,16 +277,16 @@ CDBWrapper::CDBWrapper(const DBParams& params)
CDBWrapper::~CDBWrapper()
{
delete pdb;
pdb = nullptr;
delete options.filter_policy;
options.filter_policy = nullptr;
delete options.info_log;
options.info_log = nullptr;
delete options.block_cache;
options.block_cache = nullptr;
delete penv;
options.env = nullptr;
delete DBContext().pdb;
DBContext().pdb = nullptr;
delete DBContext().options.filter_policy;
DBContext().options.filter_policy = nullptr;
delete DBContext().options.info_log;
DBContext().options.info_log = nullptr;
delete DBContext().options.block_cache;
DBContext().options.block_cache = nullptr;
delete DBContext().penv;
DBContext().options.env = nullptr;
}
bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
@ -273,7 +296,7 @@ bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
if (log_memory) {
mem_before = DynamicMemoryUsage() / 1024.0 / 1024;
}
leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.m_impl_batch->batch);
leveldb::Status status = DBContext().pdb->Write(fSync ? DBContext().syncoptions : DBContext().writeoptions, &batch.m_impl_batch->batch);
HandleError(status);
if (log_memory) {
double mem_after = DynamicMemoryUsage() / 1024.0 / 1024;
@ -287,7 +310,7 @@ size_t CDBWrapper::DynamicMemoryUsage() const
{
std::string memory;
std::optional<size_t> parsed;
if (!pdb->GetProperty("leveldb.approximate-memory-usage", &memory) || !(parsed = ToIntegral<size_t>(memory))) {
if (!DBContext().pdb->GetProperty("leveldb.approximate-memory-usage", &memory) || !(parsed = ToIntegral<size_t>(memory))) {
LogPrint(BCLog::LEVELDB, "Failed to get approximate-memory-usage property\n");
return 0;
}
@ -317,7 +340,7 @@ std::optional<std::string> CDBWrapper::ReadImpl(Span<const std::byte> ssKey) con
{
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
std::string strValue;
leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
leveldb::Status status = DBContext().pdb->Get(DBContext().readoptions, slKey, &strValue);
if (!status.ok()) {
if (status.IsNotFound())
return std::nullopt;
@ -332,7 +355,7 @@ bool CDBWrapper::ExistsImpl(Span<const std::byte> ssKey) const
leveldb::Slice slKey(CharCast(ssKey.data()), ssKey.size());
std::string strValue;
leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
leveldb::Status status = DBContext().pdb->Get(DBContext().readoptions, slKey, &strValue);
if (!status.ok()) {
if (status.IsNotFound())
return false;
@ -348,7 +371,7 @@ size_t CDBWrapper::EstimateSizeImpl(Span<const std::byte> ssKey1, Span<const std
leveldb::Slice slKey2(CharCast(ssKey2.data()), ssKey2.size());
uint64_t size = 0;
leveldb::Range range(slKey1, slKey2);
pdb->GetApproximateSizes(&range, 1, &size);
DBContext().pdb->GetApproximateSizes(&range, 1, &size);
return size;
}
@ -365,11 +388,12 @@ struct CDBIterator::IteratorImpl {
explicit IteratorImpl(leveldb::Iterator* _iter) : iter{_iter} {}
};
CDBIterator::CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter) : parent(_parent), m_impl_iter(std::move(_piter)) {}
CDBIterator::CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter) : parent(_parent),
m_impl_iter(std::move(_piter)) {}
CDBIterator* CDBWrapper::NewIterator()
{
return new CDBIterator{*this, std::make_unique<CDBIterator::IteratorImpl>(pdb->NewIterator(iteroptions))};
return new CDBIterator{*this, std::make_unique<CDBIterator::IteratorImpl>(DBContext().pdb->NewIterator(DBContext().iteroptions))};
}
void CDBIterator::SeekImpl(Span<const std::byte> ssKey)

@ -5,24 +5,21 @@
#ifndef BITCOIN_DBWRAPPER_H
#define BITCOIN_DBWRAPPER_H
#include <attributes.h>
#include <clientversion.h>
#include <serialize.h>
#include <span.h>
#include <streams.h>
#include <util/check.h>
#include <util/fs.h>
#include <cstddef>
#include <exception>
#include <leveldb/options.h>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <vector>
namespace leveldb {
class DB;
class Env;
}
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
@ -180,30 +177,14 @@ public:
}
};
struct LevelDBContext;
class CDBWrapper
{
friend const std::vector<unsigned char>& dbwrapper_private::GetObfuscateKey(const CDBWrapper &w);
private:
//! custom environment this database is using (may be nullptr in case of default environment)
leveldb::Env* penv;
//! database options used
leveldb::Options options;
//! options used when reading from the database
leveldb::ReadOptions readoptions;
//! options used when iterating over values of the database
leveldb::ReadOptions iteroptions;
//! options used when writing to the database
leveldb::WriteOptions writeoptions;
//! options used when sync writing to the database
leveldb::WriteOptions syncoptions;
//! the database itself
leveldb::DB* pdb;
//! holds all leveldb-specific fields of this class
std::unique_ptr<LevelDBContext> m_db_context;
//! the name of this database
std::string m_name;
@ -228,6 +209,7 @@ private:
std::optional<std::string> ReadImpl(Span<const std::byte> ssKey) const;
bool ExistsImpl(Span<const std::byte> ssKey) const;
size_t EstimateSizeImpl(Span<const std::byte> ssKey1, Span<const std::byte> ssKey2) const;
auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
public:
CDBWrapper(const DBParams& params);

Loading…
Cancel
Save