Bitcoin Core 29.99.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
22static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
23static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
24static const size_t DBWRAPPER_MAX_FILE_SIZE = 32 << 20; // 32 MiB
25
27struct DBOptions {
29 bool force_compact = false;
30};
31
33struct DBParams {
35 fs::path path;
39 bool memory_only = false;
41 bool wipe_data = false;
44 bool obfuscate = false;
47};
48
49class dbwrapper_error : public std::runtime_error
50{
51public:
52 explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
53};
54
55class CDBWrapper;
56
59namespace dbwrapper_private {
60
66}; // namespace dbwrapper_private
67
68bool DestroyDB(const std::string& path_str);
69
72{
73 friend class CDBWrapper;
74
75private:
77
78 struct WriteBatchImpl;
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
87public:
91 explicit CDBBatch(const CDBWrapper& _parent);
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;
113 ssKey.clear();
114 }
115
116 size_t ApproximateSize() const;
117};
118
120{
121public:
122 struct IteratorImpl;
123
124private:
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
132public:
133
138 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
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
176struct LevelDBContext;
177
179{
181private:
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
195 const fs::path m_path;
196
199
200 std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
201 bool ExistsImpl(std::span<const std::byte> key) const;
202 size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
203 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
204
205public:
206 CDBWrapper(const DBParams& params);
207 ~CDBWrapper();
208
209 CDBWrapper(const CDBWrapper&) = delete;
210 CDBWrapper& operator=(const CDBWrapper&) = delete;
211
212 template <typename K, typename V>
213 bool Read(const K& key, V& value) const
214 {
215 DataStream ssKey{};
217 ssKey << key;
218 std::optional<std::string> strValue{ReadImpl(ssKey)};
219 if (!strValue) {
220 return false;
221 }
222 try {
223 DataStream ssValue{MakeByteSpan(*strValue)};
224 m_obfuscation(ssValue);
225 ssValue >> value;
226 } catch (const std::exception&) {
227 return false;
228 }
229 return true;
230 }
231
232 template <typename K, typename V>
233 bool Write(const K& key, const V& value, bool fSync = false)
234 {
235 CDBBatch batch(*this);
236 batch.Write(key, value);
237 return WriteBatch(batch, fSync);
238 }
239
241 std::optional<fs::path> StoragePath() {
242 if (m_is_memory) {
243 return {};
244 }
245 return m_path;
246 }
247
248 template <typename K>
249 bool Exists(const K& key) const
250 {
251 DataStream ssKey{};
253 ssKey << key;
254 return ExistsImpl(ssKey);
255 }
256
257 template <typename K>
258 bool Erase(const K& key, bool fSync = false)
259 {
260 CDBBatch batch(*this);
261 batch.Erase(key);
262 return WriteBatch(batch, fSync);
263 }
264
265 bool WriteBatch(CDBBatch& batch, bool fSync = false);
266
267 // Get an estimate of LevelDB memory usage (in bytes).
268 size_t DynamicMemoryUsage() const;
269
271
275 bool IsEmpty();
276
277 template<typename K>
278 size_t EstimateSize(const K& key_begin, const K& key_end) const
279 {
280 DataStream ssKey1{}, ssKey2{};
282 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
283 ssKey1 << key_begin;
284 ssKey2 << key_end;
285 return EstimateSizeImpl(ssKey1, ssKey2);
286 }
287};
288
289#endif // BITCOIN_DBWRAPPER_H
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:106
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:72
void Erase(const K &key)
Definition: dbwrapper.h:108
void WriteImpl(std::span< const std::byte > key, DataStream &ssValue)
Definition: dbwrapper.cpp:174
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:79
DataStream ssKey
Definition: dbwrapper.h:81
void Write(const K &key, const V &value)
Definition: dbwrapper.h:96
void EraseImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:182
DataStream ssValue
Definition: dbwrapper.h:82
void Clear()
Definition: dbwrapper.cpp:169
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:160
size_t ApproximateSize() const
Definition: dbwrapper.cpp:188
const CDBWrapper & parent
Definition: dbwrapper.h:76
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:357
bool GetValue(V &value)
Definition: dbwrapper.h:164
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:126
void SeekImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:365
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:371
bool GetKey(K &key)
Definition: dbwrapper.h:154
void Seek(const K &key)
Definition: dbwrapper.h:145
const CDBWrapper & parent
Definition: dbwrapper.h:125
bool Valid() const
Definition: dbwrapper.cpp:382
void SeekToFirst()
Definition: dbwrapper.cpp:383
void Next()
Definition: dbwrapper.cpp:384
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:376
CDBWrapper(const CDBWrapper &)=delete
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:305
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:334
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:294
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:277
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:213
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:360
std::string m_name
the name of this database
Definition: dbwrapper.h:186
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:258
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:233
bool Exists(const K &key) const
Definition: dbwrapper.h:249
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:216
const fs::path m_path
path to filesystem storage
Definition: dbwrapper.h:195
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:319
Obfuscation m_obfuscation
optional XOR-obfuscation of the database
Definition: dbwrapper.h:189
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:183
CDBWrapper & operator=(const CDBWrapper &)=delete
bool m_is_memory
whether or not the database resides in memory
Definition: dbwrapper.h:198
static const std::string OBFUSCATION_KEY
obfuscation key storage key, null-prefixed to avoid collisions
Definition: dbwrapper.h:192
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:203
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:344
std::optional< fs::path > StoragePath()
Definition: dbwrapper.h:241
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:278
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:130
void reserve(size_type n)
Definition: streams.h:167
void clear()
Definition: streams.h:170
dbwrapper_error(const std::string &msg)
Definition: dbwrapper.h:52
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:22
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:38
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE
Definition: dbwrapper.h:23
static const size_t DBWRAPPER_MAX_FILE_SIZE
Definition: dbwrapper.h:24
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:386
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:388
auto MakeByteSpan(const V &v) noexcept
Definition: span.h:84
User-controlled performance and debug options.
Definition: dbwrapper.h:27
bool force_compact
Compact database on startup.
Definition: dbwrapper.h:29
Application-specific storage settings.
Definition: dbwrapper.h:33
DBOptions options
Passed-through options.
Definition: dbwrapper.h:46
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition: dbwrapper.h:44
bool wipe_data
If true, remove all existing data.
Definition: dbwrapper.h:41
size_t cache_bytes
Configures various leveldb cache settings.
Definition: dbwrapper.h:37
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition: dbwrapper.h:35
bool memory_only
If true, use leveldb's memory environment.
Definition: dbwrapper.h:39