aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheCharlatan <seb.kung@gmail.com>2023-07-14 12:31:20 +0200
committerTheCharlatan <seb.kung@gmail.com>2023-08-05 10:45:12 +0200
commitc95b37d641b1eed4a62d55ca5342a6ed8c7a1ce7 (patch)
treed0c4edda4df492400552b70d291170e9aba550f0
parentc534a615e93452a5f509aaf5f68c600391a98d6a (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.cpp84
-rw-r--r--src/dbwrapper.h32
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);