diff options
author | TheCharlatan <seb.kung@gmail.com> | 2023-07-14 12:31:20 +0200 |
---|---|---|
committer | TheCharlatan <seb.kung@gmail.com> | 2023-08-05 10:45:12 +0200 |
commit | c95b37d641b1eed4a62d55ca5342a6ed8c7a1ce7 (patch) | |
tree | d0c4edda4df492400552b70d291170e9aba550f0 | |
parent | c534a615e93452a5f509aaf5f68c600391a98d6a (diff) |
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.
-rw-r--r-- | src/dbwrapper.cpp | 84 | ||||
-rw-r--r-- | src/dbwrapper.h | 32 |
2 files changed, 61 insertions, 55 deletions
diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index 58fd47ce1c..b8ee852bb5 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -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) diff --git a/src/dbwrapper.h b/src/dbwrapper.h index fa7b6397cb..66170b5efa 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -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); |