From c95b37d641b1eed4a62d55ca5342a6ed8c7a1ce7 Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Fri, 14 Jul 2023 12:31:20 +0200 Subject: [PATCH] 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. --- src/dbwrapper.cpp | 84 ++++++++++++++++++++++++++++++----------------- src/dbwrapper.h | 32 ++++-------------- 2 files changed, 61 insertions(+), 55 deletions(-) diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 58fd47ce1ca..b8ee852bb52 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -196,23 +196,46 @@ void CDBBatch::EraseImpl(Span 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()}, 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 parsed; - if (!pdb->GetProperty("leveldb.approximate-memory-usage", &memory) || !(parsed = ToIntegral(memory))) { + if (!DBContext().pdb->GetProperty("leveldb.approximate-memory-usage", &memory) || !(parsed = ToIntegral(memory))) { LogPrint(BCLog::LEVELDB, "Failed to get approximate-memory-usage property\n"); return 0; } @@ -317,7 +340,7 @@ std::optional CDBWrapper::ReadImpl(Span 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 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 ssKey1, SpanGetApproximateSizes(&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 _piter) : parent(_parent), m_impl_iter(std::move(_piter)) {} +CDBIterator::CDBIterator(const CDBWrapper& _parent, std::unique_ptr _piter) : parent(_parent), + m_impl_iter(std::move(_piter)) {} CDBIterator* CDBWrapper::NewIterator() { - return new CDBIterator{*this, std::make_unique(pdb->NewIterator(iteroptions))}; + return new CDBIterator{*this, std::make_unique(DBContext().pdb->NewIterator(DBContext().iteroptions))}; } void CDBIterator::SeekImpl(Span ssKey) diff --git a/src/dbwrapper.h b/src/dbwrapper.h index fa7b6397cba..66170b5efa2 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -5,24 +5,21 @@ #ifndef BITCOIN_DBWRAPPER_H #define BITCOIN_DBWRAPPER_H +#include #include #include #include #include +#include #include #include #include -#include #include #include #include #include #include -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& 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 m_db_context; //! the name of this database std::string m_name; @@ -228,6 +209,7 @@ private: std::optional ReadImpl(Span ssKey) const; bool ExistsImpl(Span ssKey) const; size_t EstimateSizeImpl(Span ssKey1, Span ssKey2) const; + auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); } public: CDBWrapper(const DBParams& params);