Bitcoin Core 31.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/byte_units.h>
13#include <util/check.h>
14#include <util/fs.h>
15#include <util/obfuscation.h>
16
17#include <cstddef>
18#include <cstdint>
19#include <exception>
20#include <memory>
21#include <optional>
22#include <span>
23#include <stdexcept>
24#include <string>
25
26namespace leveldb {
27class Env;
28} // namespace leveldb
29
30static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
31static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
32static const size_t DBWRAPPER_MAX_FILE_SIZE{32_MiB};
33
35struct DBOptions {
37 bool force_compact = false;
38};
39
41struct DBParams {
43 fs::path path;
45 uint64_t cache_bytes;
47 bool memory_only = false;
49 bool wipe_data = false;
52 bool obfuscate = false;
54 bool bloom_filter = true;
59 leveldb::Env* testing_env = nullptr;
63};
64
65class dbwrapper_error : public std::runtime_error
66{
67public:
68 explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
69};
70
71class CDBWrapper;
72
75namespace dbwrapper_private {
76
82}; // namespace dbwrapper_private
83
84bool DestroyDB(const std::string& path_str);
85
88{
89 friend class CDBWrapper;
90
91private:
93
94 struct WriteBatchImpl;
95 const std::unique_ptr<WriteBatchImpl> m_impl_batch;
96
99
100 void WriteImpl(std::span<const std::byte> key, DataStream& value);
101 void EraseImpl(std::span<const std::byte> key);
102
103public:
107 explicit CDBBatch(const CDBWrapper& _parent);
109 void Clear();
110
111 template <typename K, typename V>
112 void Write(const K& key, const V& value)
113 {
114 ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
115 m_key_scratch << key;
116 m_value_scratch << value;
118 }
119
120 template <typename K>
121 void Erase(const K& key)
122 {
124 m_key_scratch << key;
126 }
127
128 size_t ApproximateSize() const;
129};
130
132{
133public:
134 struct IteratorImpl;
135
136private:
138 const std::unique_ptr<IteratorImpl> m_impl_iter;
140
141 void SeekImpl(std::span<const std::byte> key);
142 std::span<const std::byte> GetKeyImpl() const;
143 std::span<const std::byte> GetValueImpl() const;
144
145public:
146
151 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
153
154 bool Valid() const;
155
156 void SeekToFirst();
157
158 template<typename K> void Seek(const K& key) {
159 ScopedDataStreamUsage scoped_scratch{m_scratch};
160 m_scratch << key;
162 }
163
164 void Next();
165
166 template<typename K> bool GetKey(K& key) {
167 try {
168 SpanReader ssKey{GetKeyImpl()};
169 ssKey >> key;
170 } catch (const std::exception&) {
171 return false;
172 }
173 return true;
174 }
175
176 template<typename V> bool GetValue(V& value) {
177 try {
178 ScopedDataStreamUsage scoped_scratch{m_scratch};
181 m_scratch >> value;
182 } catch (const std::exception&) {
183 return false;
184 }
185 return true;
186 }
187};
188
189struct LevelDBContext;
190
192{
194private:
196 std::unique_ptr<LevelDBContext> m_db_context;
197
199 std::string m_name;
200
203
205 inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
206
207 std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
208 bool ExistsImpl(std::span<const std::byte> key) const;
209 size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
210 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
211
212public:
213 CDBWrapper(const DBParams& params);
214 ~CDBWrapper();
215
216 CDBWrapper(const CDBWrapper&) = delete;
217 CDBWrapper& operator=(const CDBWrapper&) = delete;
218
219 template <typename K, typename V>
220 bool Read(const K& key, V& value) const
221 {
222 DataStream ssKey{};
224 ssKey << key;
225 std::optional<std::string> strValue{ReadImpl(ssKey)};
226 if (!strValue) {
227 return false;
228 }
229 try {
230 std::span ssValue{MakeWritableByteSpan(*strValue)};
231 m_obfuscation(ssValue);
232 SpanReader{ssValue} >> value;
233 } catch (const std::exception&) {
234 return false;
235 }
236 return true;
237 }
238
239 template <typename K, typename V>
240 void Write(const K& key, const V& value, bool fSync = false)
241 {
242 CDBBatch batch(*this);
243 batch.Write(key, value);
244 WriteBatch(batch, fSync);
245 }
246
247 template <typename K>
248 bool Exists(const K& key) const
249 {
250 DataStream ssKey{};
252 ssKey << key;
253 return ExistsImpl(ssKey);
254 }
255
256 template <typename K>
257 void Erase(const K& key, bool fSync = false)
258 {
259 CDBBatch batch(*this);
260 batch.Erase(key);
261 WriteBatch(batch, fSync);
262 }
263
264 void WriteBatch(CDBBatch& batch, bool fSync = false);
265
267 void CompactFull();
268
270 std::optional<std::string> GetProperty(const std::string& property) const;
271
272 // Get an estimate of LevelDB memory usage (in bytes).
273 size_t DynamicMemoryUsage() const;
274
276
280 bool IsEmpty();
281
282 template<typename K>
283 size_t EstimateSize(const K& key_begin, const K& key_end) const
284 {
285 DataStream ssKey1{}, ssKey2{};
287 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
288 ssKey1 << key_begin;
289 ssKey2 << key_end;
290 return EstimateSizeImpl(ssKey1, ssKey2);
291 }
292};
293
294#endif // BITCOIN_DBWRAPPER_H
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:116
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:88
void Erase(const K &key)
Definition: dbwrapper.h:121
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:95
void WriteImpl(std::span< const std::byte > key, DataStream &value)
Definition: dbwrapper.cpp:178
void Write(const K &key, const V &value)
Definition: dbwrapper.h:112
void EraseImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:186
void Clear()
Definition: dbwrapper.cpp:171
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:160
DataStream m_key_scratch
Definition: dbwrapper.h:97
size_t ApproximateSize() const
Definition: dbwrapper.cpp:192
const CDBWrapper & parent
Definition: dbwrapper.h:92
DataStream m_value_scratch
Definition: dbwrapper.h:98
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:374
bool GetValue(V &value)
Definition: dbwrapper.h:176
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:138
void SeekImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:385
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:391
bool GetKey(K &key)
Definition: dbwrapper.h:166
DataStream m_scratch
Definition: dbwrapper.h:139
void Seek(const K &key)
Definition: dbwrapper.h:158
const CDBWrapper & parent
Definition: dbwrapper.h:137
bool Valid() const
Definition: dbwrapper.cpp:404
void SeekToFirst()
Definition: dbwrapper.cpp:405
void Next()
Definition: dbwrapper.cpp:406
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:398
CDBWrapper(const CDBWrapper &)=delete
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:322
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:351
void CompactFull()
Perform a blocking full compaction of the underlying LevelDB.
Definition: dbwrapper.cpp:310
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:312
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:220
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:380
std::string m_name
the name of this database
Definition: dbwrapper.h:199
bool Exists(const K &key) const
Definition: dbwrapper.h:248
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:220
void Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:257
void WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:288
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:336
void Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:240
Obfuscation m_obfuscation
optional XOR-obfuscation of the database
Definition: dbwrapper.h:202
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:196
CDBWrapper & operator=(const CDBWrapper &)=delete
static const std::string OBFUSCATION_KEY
obfuscation key storage key, null-prefixed to avoid collisions
Definition: dbwrapper.h:205
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:210
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:361
std::optional< std::string > GetProperty(const std::string &property) const
Return a LevelDB property value, if available.
Definition: dbwrapper.cpp:304
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:283
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:165
void write(std::span< const value_type > src)
Definition: streams.h:244
void reserve(size_type n)
Definition: streams.h:201
Minimal stream for reading from an existing byte array by std::span.
Definition: streams.h:83
dbwrapper_error(const std::string &msg)
Definition: dbwrapper.h:68
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:30
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:39
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE
Definition: dbwrapper.h:31
static const size_t DBWRAPPER_MAX_FILE_SIZE
Definition: dbwrapper.h:32
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:408
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:410
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
User-controlled performance and debug options.
Definition: dbwrapper.h:35
bool force_compact
Compact database on startup.
Definition: dbwrapper.h:37
Application-specific storage settings.
Definition: dbwrapper.h:41
DBOptions options
Passed-through options.
Definition: dbwrapper.h:56
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition: dbwrapper.h:52
size_t max_file_size
Maximum LevelDB SST file size.
Definition: dbwrapper.h:62
bool wipe_data
If true, remove all existing data.
Definition: dbwrapper.h:49
uint64_t cache_bytes
Configures various leveldb cache settings.
Definition: dbwrapper.h:45
leveldb::Env * testing_env
If non-null, use this as the leveldb::Env instead of the default.
Definition: dbwrapper.h:59
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition: dbwrapper.h:43
bool bloom_filter
If true, build a LevelDB bloom filter to accelerate point lookups.
Definition: dbwrapper.h:54
bool memory_only
If true, use leveldb's memory environment.
Definition: dbwrapper.h:47