@@ -196,23 +196,46 @@ void CDBBatch::EraseImpl(Span<const std::byte> ssKey)
196196 size_estimate += 2 + (slKey.size () > 127 ) + slKey.size ();
197197}
198198
199+ struct LevelDBContext {
200+ // ! custom environment this database is using (may be nullptr in case of default environment)
201+ leveldb::Env* penv;
202+
203+ // ! database options used
204+ leveldb::Options options;
205+
206+ // ! options used when reading from the database
207+ leveldb::ReadOptions readoptions;
208+
209+ // ! options used when iterating over values of the database
210+ leveldb::ReadOptions iteroptions;
211+
212+ // ! options used when writing to the database
213+ leveldb::WriteOptions writeoptions;
214+
215+ // ! options used when sync writing to the database
216+ leveldb::WriteOptions syncoptions;
217+
218+ // ! the database itself
219+ leveldb::DB* pdb;
220+ };
221+
199222CDBWrapper::CDBWrapper (const DBParams& params)
200- : m_name{fs::PathToString (params.path .stem ())}, m_path{params.path }, m_is_memory{params.memory_only }
223+ : m_db_context{std::make_unique<LevelDBContext>()}, m_name{fs::PathToString (params.path .stem ())}, m_path{params.path }, m_is_memory{params.memory_only }
201224{
202- penv = nullptr ;
203- readoptions.verify_checksums = true ;
204- iteroptions.verify_checksums = true ;
205- iteroptions.fill_cache = false ;
206- syncoptions.sync = true ;
207- options = GetOptions (params.cache_bytes );
208- options.create_if_missing = true ;
225+ DBContext (). penv = nullptr ;
226+ DBContext (). readoptions .verify_checksums = true ;
227+ DBContext (). iteroptions .verify_checksums = true ;
228+ DBContext (). iteroptions .fill_cache = false ;
229+ DBContext (). syncoptions .sync = true ;
230+ DBContext (). options = GetOptions (params.cache_bytes );
231+ DBContext (). options .create_if_missing = true ;
209232 if (params.memory_only ) {
210- penv = leveldb::NewMemEnv (leveldb::Env::Default ());
211- options.env = penv;
233+ DBContext (). penv = leveldb::NewMemEnv (leveldb::Env::Default ());
234+ DBContext (). options .env = DBContext (). penv ;
212235 } else {
213236 if (params.wipe_data ) {
214237 LogPrintf (" Wiping LevelDB in %s\n " , fs::PathToString (params.path ));
215- leveldb::Status result = leveldb::DestroyDB (fs::PathToString (params.path ), options);
238+ leveldb::Status result = leveldb::DestroyDB (fs::PathToString (params.path ), DBContext (). options );
216239 HandleError (result);
217240 }
218241 TryCreateDirectories (params.path );
@@ -222,13 +245,13 @@ CDBWrapper::CDBWrapper(const DBParams& params)
222245 // because on POSIX leveldb passes the byte string directly to ::open(), and
223246 // on Windows it converts from UTF-8 to UTF-16 before calling ::CreateFileW
224247 // (see env_posix.cc and env_windows.cc).
225- leveldb::Status status = leveldb::DB::Open (options, fs::PathToString (params.path ), &pdb);
248+ leveldb::Status status = leveldb::DB::Open (DBContext (). options , fs::PathToString (params.path ), &DBContext (). pdb );
226249 HandleError (status);
227250 LogPrintf (" Opened LevelDB successfully\n " );
228251
229252 if (params.options .force_compact ) {
230253 LogPrintf (" Starting database compaction of %s\n " , fs::PathToString (params.path ));
231- pdb->CompactRange (nullptr , nullptr );
254+ DBContext (). pdb ->CompactRange (nullptr , nullptr );
232255 LogPrintf (" Finished database compaction of %s\n " , fs::PathToString (params.path ));
233256 }
234257
@@ -254,16 +277,16 @@ CDBWrapper::CDBWrapper(const DBParams& params)
254277
255278CDBWrapper::~CDBWrapper ()
256279{
257- delete pdb;
258- pdb = nullptr ;
259- delete options.filter_policy ;
260- options.filter_policy = nullptr ;
261- delete options.info_log ;
262- options.info_log = nullptr ;
263- delete options.block_cache ;
264- options.block_cache = nullptr ;
265- delete penv;
266- options.env = nullptr ;
280+ delete DBContext (). pdb ;
281+ DBContext (). pdb = nullptr ;
282+ delete DBContext (). options .filter_policy ;
283+ DBContext (). options .filter_policy = nullptr ;
284+ delete DBContext (). options .info_log ;
285+ DBContext (). options .info_log = nullptr ;
286+ delete DBContext (). options .block_cache ;
287+ DBContext (). options .block_cache = nullptr ;
288+ delete DBContext (). penv ;
289+ DBContext (). options .env = nullptr ;
267290}
268291
269292bool CDBWrapper::WriteBatch (CDBBatch& batch, bool fSync )
@@ -273,7 +296,7 @@ bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
273296 if (log_memory) {
274297 mem_before = DynamicMemoryUsage () / 1024.0 / 1024 ;
275298 }
276- leveldb::Status status = pdb->Write (fSync ? syncoptions : writeoptions, &batch.m_impl_batch ->batch );
299+ leveldb::Status status = DBContext (). pdb ->Write (fSync ? DBContext (). syncoptions : DBContext (). writeoptions , &batch.m_impl_batch ->batch );
277300 HandleError (status);
278301 if (log_memory) {
279302 double mem_after = DynamicMemoryUsage () / 1024.0 / 1024 ;
@@ -287,7 +310,7 @@ size_t CDBWrapper::DynamicMemoryUsage() const
287310{
288311 std::string memory;
289312 std::optional<size_t > parsed;
290- if (!pdb->GetProperty (" leveldb.approximate-memory-usage" , &memory) || !(parsed = ToIntegral<size_t >(memory))) {
313+ if (!DBContext (). pdb ->GetProperty (" leveldb.approximate-memory-usage" , &memory) || !(parsed = ToIntegral<size_t >(memory))) {
291314 LogPrint (BCLog::LEVELDB, " Failed to get approximate-memory-usage property\n " );
292315 return 0 ;
293316 }
@@ -317,7 +340,7 @@ std::optional<std::string> CDBWrapper::ReadImpl(Span<const std::byte> ssKey) con
317340{
318341 leveldb::Slice slKey (CharCast (ssKey.data ()), ssKey.size ());
319342 std::string strValue;
320- leveldb::Status status = pdb->Get (readoptions, slKey, &strValue);
343+ leveldb::Status status = DBContext (). pdb ->Get (DBContext (). readoptions , slKey, &strValue);
321344 if (!status.ok ()) {
322345 if (status.IsNotFound ())
323346 return std::nullopt ;
@@ -332,7 +355,7 @@ bool CDBWrapper::ExistsImpl(Span<const std::byte> ssKey) const
332355 leveldb::Slice slKey (CharCast (ssKey.data ()), ssKey.size ());
333356
334357 std::string strValue;
335- leveldb::Status status = pdb->Get (readoptions, slKey, &strValue);
358+ leveldb::Status status = DBContext (). pdb ->Get (DBContext (). readoptions , slKey, &strValue);
336359 if (!status.ok ()) {
337360 if (status.IsNotFound ())
338361 return false ;
@@ -348,7 +371,7 @@ size_t CDBWrapper::EstimateSizeImpl(Span<const std::byte> ssKey1, Span<const std
348371 leveldb::Slice slKey2 (CharCast (ssKey2.data ()), ssKey2.size ());
349372 uint64_t size = 0 ;
350373 leveldb::Range range (slKey1, slKey2);
351- pdb->GetApproximateSizes (&range, 1 , &size);
374+ DBContext (). pdb ->GetApproximateSizes (&range, 1 , &size);
352375 return size;
353376}
354377
@@ -365,11 +388,12 @@ struct CDBIterator::IteratorImpl {
365388 explicit IteratorImpl (leveldb::Iterator* _iter) : iter{_iter} {}
366389};
367390
368- CDBIterator::CDBIterator (const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter) : parent(_parent), m_impl_iter(std::move(_piter)) {}
391+ CDBIterator::CDBIterator (const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter) : parent(_parent),
392+ m_impl_iter(std::move(_piter)) {}
369393
370394CDBIterator* CDBWrapper::NewIterator ()
371395{
372- return new CDBIterator{*this , std::make_unique<CDBIterator::IteratorImpl>(pdb->NewIterator (iteroptions))};
396+ return new CDBIterator{*this , std::make_unique<CDBIterator::IteratorImpl>(DBContext (). pdb ->NewIterator (DBContext (). iteroptions ))};
373397}
374398
375399void CDBIterator::SeekImpl (Span<const std::byte> ssKey)
0 commit comments