PIVX Core  5.6.99
P2P Digital Currency
dbwrapper.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2014 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef PIVX_DBWRAPPER_H
6 #define PIVX_DBWRAPPER_H
7 
8 #include "clientversion.h"
9 #include "fs.h"
10 #include "serialize.h"
11 #include "streams.h"
12 #include "util/system.h"
13 #include "version.h"
14 
15 #include <typeindex>
16 
17 #include <leveldb/db.h>
18 #include <leveldb/write_batch.h>
19 
20 
21 static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
22 static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
23 
24 
25 class dbwrapper_error : public std::runtime_error
26 {
27 public:
28  explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
29 };
30 
31 class CDBWrapper;
32 
35 namespace dbwrapper_private {
36 
39 void HandleError(const leveldb::Status& status);
40 
41 };
42 
43 
45 class CDBBatch
46 {
47  friend class CDBWrapper;
48 
49 private:
50  leveldb::WriteBatch batch;
51 
54  size_t size_estimate;
55 
56 public:
61 
62  void Clear()
63  {
64  batch.Clear();
65  size_estimate = 0;
66  }
67 
68  template <typename K, typename V>
69  void Write(const K& key, const V& value)
70  {
71  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
72  ssKey << key;
73  Write(ssKey, value);
74  ssKey.clear();
75  }
76 
77  template <typename V>
78  void Write(const CDataStream& _ssKey, const V& value)
79  {
80  leveldb::Slice slKey(_ssKey.data(), _ssKey.size());
81 
82  ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
83  ssValue << value;
84  leveldb::Slice slValue(ssValue.data(), ssValue.size());
85 
86  batch.Put(slKey, slValue);
87 
88  // LevelDB serializes writes as:
89  // - byte: header
90  // - varint: key length (1 byte up to 127B, 2 bytes up to 16383B, ...)
91  // - byte[]: key
92  // - varint: value length
93  // - byte[]: value
94  // The formula below assumes the key and value are both less than 16k.
95  size_estimate += 3 + (slKey.size() > 127) + slKey.size() + (slValue.size() > 127) + slValue.size();
96  ssValue.clear();
97  }
98 
99  template <typename K>
100  void Erase(const K& key)
101  {
102  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
103  ssKey << key;
104  Erase(ssKey);
105  ssKey.clear();
106  }
107 
108  void Erase(const CDataStream& _ssKey)
109  {
110  leveldb::Slice slKey(_ssKey.data(), _ssKey.size());
111 
112  batch.Delete(slKey);
113 
114  // LevelDB serializes erases as:
115  // - byte: header
116  // - varint: key length
117  // - byte[]: key
118  // The formula below assumes the key is less than 16kB.
119  size_estimate += 2 + (slKey.size() > 127) + slKey.size();
120  }
121 
122  size_t SizeEstimate() const { return size_estimate; }
123 };
124 
126 {
127 private:
128  leveldb::Iterator *piter;
129  int nVersion;
130 
131 public:
136  CDBIterator(leveldb::Iterator* _piter, int _nVersion) : piter(_piter), nVersion(_nVersion){};
137  ~CDBIterator();
138 
139  bool Valid();
140 
141  void SeekToFirst();
142 
143  template<typename K> void Seek(const K& key)
144  {
145  CDataStream ssKey(SER_DISK, nVersion);
146  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
147  ssKey << key;
148  Seek(ssKey);
149  }
150 
151  void Seek(const CDataStream& ssKey)
152  {
153  leveldb::Slice slKey(ssKey.data(), ssKey.size());
154  piter->Seek(slKey);
155  }
156 
157  void Next();
158 
159  template<typename K> bool GetKey(K& key)
160  {
161  try {
162  CDataStream ssKey = GetKey();
163  ssKey >> key;
164  } catch(const std::exception& e) {
165  return false;
166  }
167  return true;
168  }
169 
171  {
172  leveldb::Slice slKey = piter->key();
173  return CDataStream(slKey.data(), slKey.data() + slKey.size(), SER_DISK, nVersion);
174  }
175 
176  template<typename V> bool GetValue(V& value)
177  {
178  leveldb::Slice slValue = piter->value();
179  try {
180  CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, nVersion);
181  ssValue >> value;
182  } catch(const std::exception& e) {
183  return false;
184  }
185  return true;
186  }
187 
188  unsigned int GetValueSize()
189  {
190  return piter->value().size();
191  }
192 
193 };
194 
196 {
197 private:
199  leveldb::Env* penv;
200 
202  leveldb::Options options;
203 
205  leveldb::ReadOptions readoptions;
206 
208  leveldb::ReadOptions iteroptions;
209 
211  leveldb::WriteOptions writeoptions;
212 
214  leveldb::WriteOptions syncoptions;
215 
218 
220  int nVersion;
221 
222 public:
230  CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, int nVersion = CLIENT_VERSION);
231  ~CDBWrapper();
232 
233  template <typename K>
234  bool ReadDataStream(const K& key, CDataStream& ssValue) const
235  {
236  CDataStream ssKey(SER_DISK, nVersion);
237  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
238  ssKey << key;
239  return ReadDataStream(ssKey, ssValue);
240  }
241 
242  bool ReadDataStream(const CDataStream& ssKey, CDataStream& ssValue) const
243  {
244  leveldb::Slice slKey(ssKey.data(), ssKey.size());
245 
246  std::string strValue;
247  leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
248  if (!status.ok()) {
249  if (status.IsNotFound())
250  return false;
251  LogPrintf("LevelDB read failure: %s\n", status.ToString());
253  }
254  CDataStream ssValueTmp(strValue.data(), strValue.data() + strValue.size(), SER_DISK, nVersion);
255  ssValue = std::move(ssValueTmp);
256  return true;
257  }
258 
259  template <typename K, typename V>
260  bool Read(const K& key, V& value) const
261  {
262  CDataStream ssKey(SER_DISK, nVersion);
263  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
264  ssKey << key;
265  return Read(ssKey, value);
266  }
267 
268  template <typename V>
269  bool Read(const CDataStream& ssKey, V& value) const
270  {
271  CDataStream ssValue(SER_DISK, nVersion);
272  if (!ReadDataStream(ssKey, ssValue)) {
273  return false;
274  }
275  try {
276  ssValue >> value;
277  } catch (const std::exception&) {
278  return false;
279  }
280  return true;
281  }
282 
283  template <typename K, typename V>
284  bool Write(const K& key, const V& value, bool fSync = false)
285  {
286  CDBBatch batch(nVersion);
287  batch.Write(key, value);
288  return WriteBatch(batch, fSync);
289  }
290 
291  template <typename K>
292  bool Exists(const K& key) const
293  {
294  CDataStream ssKey(SER_DISK, nVersion);
295  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
296  ssKey << key;
297  return Exists(ssKey);
298  }
299 
300  bool Exists(const CDataStream& key) const
301  {
302  leveldb::Slice slKey(key.data(), key.size());
303 
304  std::string strValue;
305  leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
306  if (!status.ok()) {
307  if (status.IsNotFound())
308  return false;
309  LogPrintf("LevelDB read failure: %s\n", status.ToString());
311  }
312  return true;
313  }
314 
315  template <typename K>
316  bool Erase(const K& key, bool fSync = false)
317  {
318  CDBBatch batch(nVersion);
319  batch.Erase(key);
320  return WriteBatch(batch, fSync);
321  }
322 
323  bool WriteBatch(CDBBatch& batch, bool fSync = false);
324 
325  // not available for LevelDB; provide for compatibility with BDB
326  bool Flush()
327  {
328  return true;
329  }
330 
331  bool Sync()
332  {
333  CDBBatch batch(nVersion);
334  return WriteBatch(batch, true);
335  }
336 
337  // not exactly clean encapsulation, but it's easiest for now
339  {
340  return new CDBIterator(pdb->NewIterator(iteroptions), nVersion);
341  }
342 
346  bool IsEmpty();
347 
348  template<typename K>
349  size_t EstimateSize(const K& key_begin, const K& key_end) const
350  {
351  CDataStream ssKey1(SER_DISK, nVersion), ssKey2(SER_DISK, nVersion);
352  ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
353  ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
354  ssKey1 << key_begin;
355  ssKey2 << key_end;
356  leveldb::Slice slKey1(&ssKey1[0], ssKey1.size());
357  leveldb::Slice slKey2(&ssKey2[0], ssKey2.size());
358  uint64_t size = 0;
359  leveldb::Range range(slKey1, slKey2);
360  pdb->GetApproximateSizes(&range, 1, &size);
361  return size;
362  }
363 
367  template<typename K>
368  void CompactRange(const K& key_begin, const K& key_end) const
369  {
370  CDataStream ssKey1(SER_DISK, nVersion), ssKey2(SER_DISK, nVersion);
371  ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
372  ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
373  ssKey1 << key_begin;
374  ssKey2 << key_end;
375  leveldb::Slice slKey1(ssKey1.data(), ssKey1.size());
376  leveldb::Slice slKey2(ssKey2.data(), ssKey2.size());
377  pdb->CompactRange(&slKey1, &slKey2);
378  }
379 
380  void CompactFull() const
381  {
382  pdb->CompactRange(nullptr, nullptr);
383  }
384 
385 };
386 
387 template<typename CDBTransaction>
389 {
390 private:
392 
393  typedef typename std::remove_pointer<decltype(transaction.parent.NewIterator())>::type ParentIterator;
394 
395  // We maintain 2 iterators, one for the transaction and one for the parent
396  // At all times, only one of both provides the current value. The decision is made by comparing the current keys
397  // of both iterators, so that always the smaller key is the current one. On Next(), the previously chosen iterator
398  // is advanced.
399  typename CDBTransaction::WritesMap::iterator transactionIt;
400  std::unique_ptr<ParentIterator> parentIt;
402  int nVersion;
403  bool curIsParent{false};
404 
405 public:
406  CDBTransactionIterator(CDBTransaction& _transaction, int _nVersion) : transaction(_transaction),
407  parentKey(SER_DISK, _nVersion),
408  nVersion(_nVersion)
409  {
411  parentIt = std::unique_ptr<ParentIterator>(transaction.parent.NewIterator());
412  }
413 
414  void SeekToFirst()
415  {
416  transactionIt = transaction.writes.begin();
417  parentIt->SeekToFirst();
419  DecideCur();
420  }
421 
422  template<typename K>
423  void Seek(const K& key)
424  {
426  }
427 
428  void Seek(const CDataStream& ssKey)
429  {
430  transactionIt = transaction.writes.lower_bound(ssKey);
431  parentIt->Seek(ssKey);
433  DecideCur();
434  }
435 
436  bool Valid()
437  {
438  return transactionIt != transaction.writes.end() || parentIt->Valid();
439  }
440 
441  void Next()
442  {
443  if (transactionIt == transaction.writes.end() && !parentIt->Valid()) {
444  return;
445  }
446  if (curIsParent) {
447  assert(parentIt->Valid());
448  parentIt->Next();
450  } else {
451  assert(transactionIt != transaction.writes.end());
452  ++transactionIt;
453  }
454  DecideCur();
455  }
456 
457  template<typename K>
458  bool GetKey(K& key)
459  {
460  if (!Valid()) {
461  return false;
462  }
463 
464  if (curIsParent) {
465  return parentIt->GetKey(key);
466  } else {
467  try {
468  // TODO try to avoid this copy (we need a stream that allows reading from external buffers)
469  CDataStream ssKey = transactionIt->first;
470  ssKey >> key;
471  } catch (const std::exception&) {
472  return false;
473  }
474  return true;
475  }
476  }
477 
479  {
480  if (!Valid()) {
481  return CDataStream(SER_DISK, nVersion);
482  }
483  if (curIsParent) {
484  return parentIt->GetKey();
485  } else {
486  return transactionIt->first;
487  }
488  }
489 
490  template<typename V>
491  bool GetValue(V& value)
492  {
493  if (!Valid()) {
494  return false;
495  }
496  if (curIsParent) {
497  return transaction.Read(parentKey, value);
498  } else {
499  return transaction.Read(transactionIt->first, value);
500  }
501  };
502 
503 private:
505  {
506  while (parentIt->Valid()) {
507  parentKey = parentIt->GetKey();
508  if (!transaction.deletes.count(parentKey) && !transaction.writes.count(parentKey)) {
509  break;
510  }
511  parentIt->Next();
512  }
513  }
514 
515  void DecideCur()
516  {
517  if (transactionIt != transaction.writes.end() && !parentIt->Valid()) {
518  curIsParent = false;
519  } else if (transactionIt == transaction.writes.end() && parentIt->Valid()) {
520  curIsParent = true;
521  } else if (transactionIt != transaction.writes.end() && parentIt->Valid()) {
523  curIsParent = false;
524  } else {
525  curIsParent = true;
526  }
527  }
528  }
529 };
530 
531 template<typename Parent, typename CommitTarget>
534 
535 protected:
536  Parent &parent;
537  CommitTarget &commitTarget;
538  ssize_t memoryUsage{0}; // signed, just in case we made an error in the calculations so that we don't get an overflow
539 
540  struct DataStreamCmp {
541  static bool less(const CDataStream& a, const CDataStream& b)
542  {
543  return std::lexicographical_compare(
544  (const uint8_t*)a.data(), (const uint8_t*)a.data() + a.size(),
545  (const uint8_t*)b.data(), (const uint8_t*)b.data() + b.size());
546  }
547  bool operator()(const CDataStream& a, const CDataStream& b) const { return less(a, b); }
548  };
549 
550  struct ValueHolder {
551  size_t memoryUsage;
552  ValueHolder(size_t _memoryUsage) : memoryUsage(_memoryUsage) {}
553  virtual ~ValueHolder() = default;
554  virtual void Write(const CDataStream& ssKey, CommitTarget &parent) = 0;
555  };
556  typedef std::unique_ptr<ValueHolder> ValueHolderPtr;
557 
558  template <typename V>
560  ValueHolderImpl(const V &_value, size_t _memoryUsage) : ValueHolder(_memoryUsage), value(_value) {}
561 
562  virtual void Write(const CDataStream& ssKey, CommitTarget &commitTarget)
563  {
564  // we're moving the value instead of copying it. This means that Write() can only be called once per
565  // ValueHolderImpl instance. Commit() clears the write maps, so this ok.
566  commitTarget.Write(ssKey, std::move(value));
567  }
568  V value;
569  };
570 
571  template <typename K>
572  static CDataStream KeyToDataStream(const K& key, int nVersion)
573  {
574  CDataStream ssKey(SER_DISK, nVersion);
575  ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
576  ssKey << key;
577  return ssKey;
578  }
579 
580  typedef std::map<CDataStream, ValueHolderPtr, DataStreamCmp> WritesMap;
581  typedef std::set<CDataStream, DataStreamCmp> DeletesSet;
582 
585  int nVersion;
586 
587 public:
588  CDBTransaction(Parent& _parent, CommitTarget& _commitTarget, int _nVersion) : parent(_parent), commitTarget(_commitTarget), nVersion(_nVersion) {}
589 
590  template <typename K, typename V>
591  void Write(const K& key, const V& v)
592  {
593  Write(KeyToDataStream(key, nVersion), v);
594  }
595 
596  template <typename V>
597  void Write(const CDataStream& ssKey, const V& v)
598  {
599  auto valueMemoryUsage = ::GetSerializeSize(v, nVersion);
600  if (deletes.erase(ssKey)) {
601  memoryUsage -= ssKey.size();
602  }
603  auto it = writes.emplace(ssKey, nullptr).first;
604  if (it->second) {
605  memoryUsage -= ssKey.size() + it->second->memoryUsage;
606  }
607  it->second = std::make_unique<ValueHolderImpl<V>>(v, valueMemoryUsage);
608 
609  memoryUsage += ssKey.size() + valueMemoryUsage;
610  }
611 
612  template <typename K, typename V>
613  bool Read(const K& key, V& value)
614  {
615  return Read(KeyToDataStream(key, nVersion), value);
616  }
617 
618  template <typename V>
619  bool Read(const CDataStream& ssKey, V& value)
620  {
621  if (deletes.count(ssKey)) {
622  return false;
623  }
624 
625  auto it = writes.find(ssKey);
626  if (it != writes.end()) {
627  auto *impl = dynamic_cast<ValueHolderImpl<V> *>(it->second.get());
628  if (!impl) {
629  throw std::runtime_error("Read called with V != previously written type");
630  }
631  value = impl->value;
632  return true;
633  }
634 
635  return parent.Read(ssKey, value);
636  }
637 
638  template <typename K>
639  bool Exists(const K& key)
640  {
641  return Exists(KeyToDataStream(key, nVersion));
642  }
643 
644  bool Exists(const CDataStream& ssKey)
645  {
646  if (deletes.count(ssKey)) {
647  return false;
648  }
649 
650  if (writes.count(ssKey)) {
651  return true;
652  }
653 
654  return parent.Exists(ssKey);
655  }
656 
657  template <typename K>
658  void Erase(const K& key)
659  {
660  return Erase(KeyToDataStream(key, nVersion));
661  }
662 
663  void Erase(const CDataStream& ssKey)
664  {
665  auto it = writes.find(ssKey);
666  if (it != writes.end()) {
667  memoryUsage -= ssKey.size() + it->second->memoryUsage;
668  writes.erase(it);
669  }
670  if (deletes.emplace(ssKey).second) {
671  memoryUsage += ssKey.size();
672  }
673  }
674 
675  void Clear()
676  {
677  writes.clear();
678  deletes.clear();
679  memoryUsage = 0;
680  }
681 
682  void Commit()
683  {
684  for (const auto &k : deletes) {
685  commitTarget.Erase(k);
686  }
687  for (auto &p : writes) {
688  p.second->Write(p.first, commitTarget);
689  }
690  Clear();
691  }
692 
693  bool IsClean()
694  {
695  return writes.empty() && deletes.empty();
696  }
697 
698  size_t GetMemoryUsage() const
699  {
700  if (memoryUsage < 0) {
701  // something went wrong when we accounted/calculated used memory...
702  static volatile bool didPrint = false;
703  if (!didPrint) {
704  LogPrintf("CDBTransaction::%s -- negative memoryUsage (%d)", __func__, memoryUsage);
705  didPrint = true;
706  }
707  return 0;
708  }
709  return (size_t)memoryUsage;
710  }
711 
713  {
715  }
716  std::unique_ptr<CDBTransactionIterator<CDBTransaction>> NewIteratorUniquePtr()
717  {
718  return std::make_unique<CDBTransactionIterator<CDBTransaction>>(*this, nVersion);
719  }
720 };
721 
722 #endif // PIVX_DBWRAPPER_H
value_type * data()
Definition: streams.h:178
size_type size() const
Definition: streams.h:165
void reserve(size_type n)
Definition: streams.h:168
void clear()
Definition: streams.h:171
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:46
void Erase(const K &key)
Definition: dbwrapper.h:100
void Write(const CDataStream &_ssKey, const V &value)
Definition: dbwrapper.h:78
void Erase(const CDataStream &_ssKey)
Definition: dbwrapper.h:108
size_t SizeEstimate() const
Definition: dbwrapper.h:122
CDataStream ssKey
Definition: dbwrapper.h:52
CDataStream ssValue
Definition: dbwrapper.h:53
CDBBatch(int nVersion)
Definition: dbwrapper.h:60
size_t size_estimate
Definition: dbwrapper.h:54
void Write(const K &key, const V &value)
Definition: dbwrapper.h:69
void Clear()
Definition: dbwrapper.h:62
leveldb::WriteBatch batch
Definition: dbwrapper.h:50
bool GetValue(V &value)
Definition: dbwrapper.h:176
bool Valid()
Definition: dbwrapper.cpp:109
CDataStream GetKey()
Definition: dbwrapper.h:170
int nVersion
Definition: dbwrapper.h:129
unsigned int GetValueSize()
Definition: dbwrapper.h:188
bool GetKey(K &key)
Definition: dbwrapper.h:159
leveldb::Iterator * piter
Definition: dbwrapper.h:128
void Seek(const K &key)
Definition: dbwrapper.h:143
void Seek(const CDataStream &ssKey)
Definition: dbwrapper.h:151
void SeekToFirst()
Definition: dbwrapper.cpp:110
void Next()
Definition: dbwrapper.cpp:111
CDBIterator(leveldb::Iterator *_piter, int _nVersion)
Definition: dbwrapper.h:136
void Clear()
Definition: dbwrapper.h:675
void Commit()
Definition: dbwrapper.h:682
void Write(const K &key, const V &v)
Definition: dbwrapper.h:591
void Erase(const K &key)
Definition: dbwrapper.h:658
std::unique_ptr< ValueHolder > ValueHolderPtr
Definition: dbwrapper.h:556
bool Exists(const K &key)
Definition: dbwrapper.h:639
std::map< CDataStream, ValueHolderPtr, DataStreamCmp > WritesMap
Definition: dbwrapper.h:580
bool Read(const CDataStream &ssKey, V &value)
Definition: dbwrapper.h:619
CommitTarget & commitTarget
Definition: dbwrapper.h:537
bool IsClean()
Definition: dbwrapper.h:693
CDBTransaction(Parent &_parent, CommitTarget &_commitTarget, int _nVersion)
Definition: dbwrapper.h:588
static CDataStream KeyToDataStream(const K &key, int nVersion)
Definition: dbwrapper.h:572
ssize_t memoryUsage
Definition: dbwrapper.h:538
void Write(const CDataStream &ssKey, const V &v)
Definition: dbwrapper.h:597
std::set< CDataStream, DataStreamCmp > DeletesSet
Definition: dbwrapper.h:581
CDBTransactionIterator< CDBTransaction > * NewIterator()
Definition: dbwrapper.h:712
void Erase(const CDataStream &ssKey)
Definition: dbwrapper.h:663
WritesMap writes
Definition: dbwrapper.h:583
DeletesSet deletes
Definition: dbwrapper.h:584
bool Read(const K &key, V &value)
Definition: dbwrapper.h:613
std::unique_ptr< CDBTransactionIterator< CDBTransaction > > NewIteratorUniquePtr()
Definition: dbwrapper.h:716
Parent & parent
Definition: dbwrapper.h:536
bool Exists(const CDataStream &ssKey)
Definition: dbwrapper.h:644
friend class CDBTransactionIterator< CDBTransaction >
Definition: dbwrapper.h:533
size_t GetMemoryUsage() const
Definition: dbwrapper.h:698
CDataStream parentKey
Definition: dbwrapper.h:401
bool GetKey(K &key)
Definition: dbwrapper.h:458
CDataStream GetKey()
Definition: dbwrapper.h:478
bool GetValue(V &value)
Definition: dbwrapper.h:491
CDBTransactionIterator(CDBTransaction &_transaction, int _nVersion)
Definition: dbwrapper.h:406
void Seek(const CDataStream &ssKey)
Definition: dbwrapper.h:428
std::unique_ptr< ParentIterator > parentIt
Definition: dbwrapper.h:400
CDBTransaction::WritesMap::iterator transactionIt
Definition: dbwrapper.h:399
void Seek(const K &key)
Definition: dbwrapper.h:423
void SkipDeletedAndOverwritten()
Definition: dbwrapper.h:504
CDBTransaction & transaction
Definition: dbwrapper.h:391
std::remove_pointer< decltype(transaction.parent.NewIterator())>::type ParentIterator
Definition: dbwrapper.h:393
CDBIterator * NewIterator()
Definition: dbwrapper.h:338
bool Exists(const CDataStream &key) const
Definition: dbwrapper.h:300
leveldb::Env * penv
custom environment this database is using (may be nullptr in case of default environment)
Definition: dbwrapper.h:199
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:94
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:260
CDBWrapper(const fs::path &path, size_t nCacheSize, bool fMemory=false, bool fWipe=false, int nVersion=CLIENT_VERSION)
Definition: dbwrapper.cpp:55
void CompactFull() const
Definition: dbwrapper.h:380
bool Flush()
Definition: dbwrapper.h:326
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:316
bool ReadDataStream(const K &key, CDataStream &ssValue) const
Definition: dbwrapper.h:234
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:284
bool Exists(const K &key) const
Definition: dbwrapper.h:292
bool Read(const CDataStream &ssKey, V &value) const
Definition: dbwrapper.h:269
leveldb::Options options
database options used
Definition: dbwrapper.h:202
bool ReadDataStream(const CDataStream &ssKey, CDataStream &ssValue) const
Definition: dbwrapper.h:242
leveldb::WriteOptions writeoptions
options used when writing to the database
Definition: dbwrapper.h:211
leveldb::WriteOptions syncoptions
options used when sync writing to the database
Definition: dbwrapper.h:214
int nVersion
the version used to serialize data
Definition: dbwrapper.h:220
leveldb::DB * pdb
the database itself
Definition: dbwrapper.h:217
leveldb::ReadOptions iteroptions
options used when iterating over values of the database
Definition: dbwrapper.h:208
void CompactRange(const K &key_begin, const K &key_end) const
Compact a certain range of keys in the database.
Definition: dbwrapper.h:368
bool Sync()
Definition: dbwrapper.h:331
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:101
leveldb::ReadOptions readoptions
options used when reading from the database
Definition: dbwrapper.h:205
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:349
dbwrapper_error(const std::string &msg)
Definition: dbwrapper.h:28
@ DB
Definition: logging.h:47
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:114
void HandleError(const leveldb::Status &status)
Handle database error by throwing dbwrapper_error exception.
Definition: dbwrapper.cpp:116
Definition: uint256.h:212
@ SER_DISK
Definition: serialize.h:175
unsigned int GetSerializeSize(const std::array< T, N > &item)
array
Definition: serialize.h:847
bool operator()(const CDataStream &a, const CDataStream &b) const
Definition: dbwrapper.h:547
static bool less(const CDataStream &a, const CDataStream &b)
Definition: dbwrapper.h:541
ValueHolder(size_t _memoryUsage)
Definition: dbwrapper.h:552
virtual void Write(const CDataStream &ssKey, CommitTarget &parent)=0
virtual ~ValueHolder()=default
ValueHolderImpl(const V &_value, size_t _memoryUsage)
Definition: dbwrapper.h:560
virtual void Write(const CDataStream &ssKey, CommitTarget &commitTarget)
Definition: dbwrapper.h:562