@@ -196,23 +196,46 @@ void CDBBatch::EraseImpl(Span<const std::byte> ssKey)
196
196
size_estimate += 2 + (slKey.size () > 127 ) + slKey.size ();
197
197
}
198
198
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
+
199
222
CDBWrapper::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 }
201
224
{
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 ;
209
232
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 ;
212
235
} else {
213
236
if (params.wipe_data ) {
214
237
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 );
216
239
HandleError (result);
217
240
}
218
241
TryCreateDirectories (params.path );
@@ -222,13 +245,13 @@ CDBWrapper::CDBWrapper(const DBParams& params)
222
245
// because on POSIX leveldb passes the byte string directly to ::open(), and
223
246
// on Windows it converts from UTF-8 to UTF-16 before calling ::CreateFileW
224
247
// (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 );
226
249
HandleError (status);
227
250
LogPrintf (" Opened LevelDB successfully\n " );
228
251
229
252
if (params.options .force_compact ) {
230
253
LogPrintf (" Starting database compaction of %s\n " , fs::PathToString (params.path ));
231
- pdb->CompactRange (nullptr , nullptr );
254
+ DBContext (). pdb ->CompactRange (nullptr , nullptr );
232
255
LogPrintf (" Finished database compaction of %s\n " , fs::PathToString (params.path ));
233
256
}
234
257
@@ -254,16 +277,16 @@ CDBWrapper::CDBWrapper(const DBParams& params)
254
277
255
278
CDBWrapper::~CDBWrapper ()
256
279
{
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 ;
267
290
}
268
291
269
292
bool CDBWrapper::WriteBatch (CDBBatch& batch, bool fSync )
@@ -273,7 +296,7 @@ bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
273
296
if (log_memory) {
274
297
mem_before = DynamicMemoryUsage () / 1024.0 / 1024 ;
275
298
}
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 );
277
300
HandleError (status);
278
301
if (log_memory) {
279
302
double mem_after = DynamicMemoryUsage () / 1024.0 / 1024 ;
@@ -287,7 +310,7 @@ size_t CDBWrapper::DynamicMemoryUsage() const
287
310
{
288
311
std::string memory;
289
312
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))) {
291
314
LogPrint (BCLog::LEVELDB, " Failed to get approximate-memory-usage property\n " );
292
315
return 0 ;
293
316
}
@@ -317,7 +340,7 @@ std::optional<std::string> CDBWrapper::ReadImpl(Span<const std::byte> ssKey) con
317
340
{
318
341
leveldb::Slice slKey (CharCast (ssKey.data ()), ssKey.size ());
319
342
std::string strValue;
320
- leveldb::Status status = pdb->Get (readoptions, slKey, &strValue);
343
+ leveldb::Status status = DBContext (). pdb ->Get (DBContext (). readoptions , slKey, &strValue);
321
344
if (!status.ok ()) {
322
345
if (status.IsNotFound ())
323
346
return std::nullopt;
@@ -332,7 +355,7 @@ bool CDBWrapper::ExistsImpl(Span<const std::byte> ssKey) const
332
355
leveldb::Slice slKey (CharCast (ssKey.data ()), ssKey.size ());
333
356
334
357
std::string strValue;
335
- leveldb::Status status = pdb->Get (readoptions, slKey, &strValue);
358
+ leveldb::Status status = DBContext (). pdb ->Get (DBContext (). readoptions , slKey, &strValue);
336
359
if (!status.ok ()) {
337
360
if (status.IsNotFound ())
338
361
return false ;
@@ -348,7 +371,7 @@ size_t CDBWrapper::EstimateSizeImpl(Span<const std::byte> ssKey1, Span<const std
348
371
leveldb::Slice slKey2 (CharCast (ssKey2.data ()), ssKey2.size ());
349
372
uint64_t size = 0 ;
350
373
leveldb::Range range (slKey1, slKey2);
351
- pdb->GetApproximateSizes (&range, 1 , &size);
374
+ DBContext (). pdb ->GetApproximateSizes (&range, 1 , &size);
352
375
return size;
353
376
}
354
377
@@ -365,11 +388,12 @@ struct CDBIterator::IteratorImpl {
365
388
explicit IteratorImpl (leveldb::Iterator* _iter) : iter{_iter} {}
366
389
};
367
390
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)) {}
369
393
370
394
CDBIterator* CDBWrapper::NewIterator ()
371
395
{
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 ))};
373
397
}
374
398
375
399
void CDBIterator::SeekImpl (Span<const std::byte> ssKey)
0 commit comments