Bitcoin Core  31.0.0
P2P Digital Currency
dbwrapper.h
Go to the documentation of this file.
1 // Copyright (c) 2012-present The Bitcoin Core 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 BITCOIN_DBWRAPPER_H
6 #define BITCOIN_DBWRAPPER_H
7 
8 #include <attributes.h>
9 #include <serialize.h>
10 #include <span.h>
11 #include <streams.h>
12 #include <util/check.h>
13 #include <util/fs.h>
14 
15 #include <cstddef>
16 #include <exception>
17 #include <memory>
18 #include <optional>
19 #include <stdexcept>
20 #include <string>
21 
22 static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
23 static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
24 static const size_t DBWRAPPER_MAX_FILE_SIZE = 32 << 20; // 32 MiB
25 
27 struct DBOptions {
29  bool force_compact = false;
30 };
31 
33 struct DBParams {
37  size_t cache_bytes;
39  bool memory_only = false;
41  bool wipe_data = false;
44  bool obfuscate = false;
47 };
48 
49 class dbwrapper_error : public std::runtime_error
50 {
51 public:
52  explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
53 };
54 
55 class CDBWrapper;
56 
59 namespace dbwrapper_private {
60 
66 }; // namespace dbwrapper_private
67 
68 bool DestroyDB(const std::string& path_str);
69 
71 class CDBBatch
72 {
73  friend class CDBWrapper;
74 
75 private:
77 
79  const std::unique_ptr<WriteBatchImpl> m_impl_batch;
80 
83 
84  void WriteImpl(std::span<const std::byte> key, DataStream& ssValue);
85  void EraseImpl(std::span<const std::byte> key);
86 
87 public:
91  explicit CDBBatch(const CDBWrapper& _parent);
92  ~CDBBatch();
93  void Clear();
94 
95  template <typename K, typename V>
96  void Write(const K& key, const V& value)
97  {
100  ssKey << key;
101  ssValue << value;
103  ssKey.clear();
104  ssValue.clear();
105  }
106 
107  template <typename K>
108  void Erase(const K& key)
109  {
111  ssKey << key;
112  EraseImpl(ssKey);
113  ssKey.clear();
114  }
115 
116  size_t ApproximateSize() const;
117 };
118 
120 {
121 public:
122  struct IteratorImpl;
123 
124 private:
125  const CDBWrapper &parent;
126  const std::unique_ptr<IteratorImpl> m_impl_iter;
127 
128  void SeekImpl(std::span<const std::byte> key);
129  std::span<const std::byte> GetKeyImpl() const;
130  std::span<const std::byte> GetValueImpl() const;
131 
132 public:
133 
138  CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
139  ~CDBIterator();
140 
141  bool Valid() const;
142 
143  void SeekToFirst();
144 
145  template<typename K> void Seek(const K& key) {
146  DataStream ssKey{};
148  ssKey << key;
149  SeekImpl(ssKey);
150  }
151 
152  void Next();
153 
154  template<typename K> bool GetKey(K& key) {
155  try {
156  DataStream ssKey{GetKeyImpl()};
157  ssKey >> key;
158  } catch (const std::exception&) {
159  return false;
160  }
161  return true;
162  }
163 
164  template<typename V> bool GetValue(V& value) {
165  try {
166  DataStream ssValue{GetValueImpl()};
168  ssValue >> value;
169  } catch (const std::exception&) {
170  return false;
171  }
172  return true;
173  }
174 };
175 
176 struct LevelDBContext;
177 
179 {
181 private:
183  std::unique_ptr<LevelDBContext> m_db_context;
184 
186  std::string m_name;
187 
190 
192  inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
193 
194  std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
195  bool ExistsImpl(std::span<const std::byte> key) const;
196  size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
197  auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
198 
199 public:
200  CDBWrapper(const DBParams& params);
201  ~CDBWrapper();
202 
203  CDBWrapper(const CDBWrapper&) = delete;
204  CDBWrapper& operator=(const CDBWrapper&) = delete;
205 
206  template <typename K, typename V>
207  bool Read(const K& key, V& value) const
208  {
209  DataStream ssKey{};
211  ssKey << key;
212  std::optional<std::string> strValue{ReadImpl(ssKey)};
213  if (!strValue) {
214  return false;
215  }
216  try {
217  std::span ssValue{MakeWritableByteSpan(*strValue)};
218  m_obfuscation(ssValue);
219  SpanReader{ssValue} >> value;
220  } catch (const std::exception&) {
221  return false;
222  }
223  return true;
224  }
225 
226  template <typename K, typename V>
227  void Write(const K& key, const V& value, bool fSync = false)
228  {
229  CDBBatch batch(*this);
230  batch.Write(key, value);
231  WriteBatch(batch, fSync);
232  }
233 
234  template <typename K>
235  bool Exists(const K& key) const
236  {
237  DataStream ssKey{};
239  ssKey << key;
240  return ExistsImpl(ssKey);
241  }
242 
243  template <typename K>
244  void Erase(const K& key, bool fSync = false)
245  {
246  CDBBatch batch(*this);
247  batch.Erase(key);
248  WriteBatch(batch, fSync);
249  }
250 
251  void WriteBatch(CDBBatch& batch, bool fSync = false);
252 
253  // Get an estimate of LevelDB memory usage (in bytes).
254  size_t DynamicMemoryUsage() const;
255 
257 
261  bool IsEmpty();
262 
263  template<typename K>
264  size_t EstimateSize(const K& key_begin, const K& key_end) const
265  {
266  DataStream ssKey1{}, ssKey2{};
268  ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
269  ssKey1 << key_begin;
270  ssKey2 << key_end;
271  return EstimateSizeImpl(ssKey1, ssKey2);
272  }
273 };
274 
275 #endif // BITCOIN_DBWRAPPER_H
bool Exists(const K &key) const
Definition: dbwrapper.h:235
bool GetKey(K &key)
Definition: dbwrapper.h:154
dbwrapper_error(const std::string &msg)
Definition: dbwrapper.h:52
void SeekImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:365
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition: dbwrapper.h:35
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:386
void Clear()
Definition: dbwrapper.cpp:170
void EraseImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:183
void reserve(size_type n)
Definition: streams.h:170
static const size_t DBWRAPPER_MAX_FILE_SIZE
Definition: dbwrapper.h:24
void WriteImpl(std::span< const std::byte > key, DataStream &ssValue)
Definition: dbwrapper.cpp:175
void SeekToFirst()
Definition: dbwrapper.cpp:383
size_t ApproximateSize() const
Definition: dbwrapper.cpp:189
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:71
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:388
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:197
void Erase(const K &key)
Definition: dbwrapper.h:108
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:22
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:334
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:39
Definition: common.h:29
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:126
DBOptions options
Passed-through options.
Definition: dbwrapper.h:46
User-controlled performance and debug options.
Definition: dbwrapper.h:27
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:357
Minimal stream for reading from an existing byte array by std::span.
Definition: streams.h:82
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:294
const CDBWrapper & parent
Definition: dbwrapper.h:122
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:371
bool GetValue(V &value)
Definition: dbwrapper.h:164
void Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:244
DataStream ssValue
Definition: dbwrapper.h:82
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:376
void Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:227
const CDBWrapper & parent
Definition: dbwrapper.h:76
CDBWrapper & operator=(const CDBWrapper &)=delete
#define LIFETIMEBOUND
Definition: attributes.h:16
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:217
void WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:278
static const std::string OBFUSCATION_KEY
obfuscation key storage key, null-prefixed to avoid collisions
Definition: dbwrapper.h:192
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:132
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:360
Obfuscation m_obfuscation
optional XOR-obfuscation of the database
Definition: dbwrapper.h:189
void Write(const K &key, const V &value)
Definition: dbwrapper.h:96
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
bool wipe_data
If true, remove all existing data.
Definition: dbwrapper.h:41
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:344
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:207
bool force_compact
Compact database on startup.
Definition: dbwrapper.h:29
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition: dbwrapper.h:44
void Next()
Definition: dbwrapper.cpp:384
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE
Definition: dbwrapper.h:23
std::string m_name
the name of this database
Definition: dbwrapper.h:186
void clear()
Definition: streams.h:173
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:183
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:319
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:305
void Seek(const K &key)
Definition: dbwrapper.h:145
Application-specific storage settings.
Definition: dbwrapper.h:33
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:161
bool Valid() const
Definition: dbwrapper.cpp:382
size_t cache_bytes
Configures various leveldb cache settings.
Definition: dbwrapper.h:37
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:78
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:264
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
bool memory_only
If true, use leveldb&#39;s memory environment.
Definition: dbwrapper.h:39
#define Assert(val)
Identity function.
Definition: check.h:113
DataStream ssKey
Definition: dbwrapper.h:81