Bitcoin Core 30.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
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
199public:
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 DataStream ssValue{MakeByteSpan(*strValue)};
218 m_obfuscation(ssValue);
219 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
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:113
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:356
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:364
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:370
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:381
void SeekToFirst()
Definition: dbwrapper.cpp:382
void Next()
Definition: dbwrapper.cpp:383
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:375
CDBWrapper(const CDBWrapper &)=delete
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:304
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:333
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:293
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:207
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:359
std::string m_name
the name of this database
Definition: dbwrapper.h:186
bool Exists(const K &key) const
Definition: dbwrapper.h:235
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:216
void Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:244
void WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:277
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:318
void Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:227
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
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:197
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:343
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:264
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:385
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:387
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