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
16#include <cstddef>
17#include <exception>
18#include <memory>
19#include <optional>
20#include <stdexcept>
21#include <string>
22
23namespace leveldb {
24class Env;
25} // namespace leveldb
26
27static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
28static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
29static const size_t DBWRAPPER_MAX_FILE_SIZE{32_MiB};
30
32struct DBOptions {
34 bool force_compact = false;
35};
36
38struct DBParams {
40 fs::path path;
44 bool memory_only = false;
46 bool wipe_data = false;
49 bool obfuscate = false;
54 leveldb::Env* testing_env = nullptr;
58};
59
60class dbwrapper_error : public std::runtime_error
61{
62public:
63 explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
64};
65
66class CDBWrapper;
67
70namespace dbwrapper_private {
71
77}; // namespace dbwrapper_private
78
79bool DestroyDB(const std::string& path_str);
80
83{
84 friend class CDBWrapper;
85
86private:
88
89 struct WriteBatchImpl;
90 const std::unique_ptr<WriteBatchImpl> m_impl_batch;
91
94
95 void WriteImpl(std::span<const std::byte> key, DataStream& value);
96 void EraseImpl(std::span<const std::byte> key);
97
98public:
102 explicit CDBBatch(const CDBWrapper& _parent);
104 void Clear();
105
106 template <typename K, typename V>
107 void Write(const K& key, const V& value)
108 {
109 ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
110 m_key_scratch << key;
111 m_value_scratch << value;
113 }
114
115 template <typename K>
116 void Erase(const K& key)
117 {
119 m_key_scratch << key;
121 }
122
123 size_t ApproximateSize() const;
124};
125
127{
128public:
129 struct IteratorImpl;
130
131private:
133 const std::unique_ptr<IteratorImpl> m_impl_iter;
135
136 void SeekImpl(std::span<const std::byte> key);
137 std::span<const std::byte> GetKeyImpl() const;
138 std::span<const std::byte> GetValueImpl() const;
139
140public:
141
146 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
148
149 bool Valid() const;
150
151 void SeekToFirst();
152
153 template<typename K> void Seek(const K& key) {
154 ScopedDataStreamUsage scoped_scratch{m_scratch};
155 m_scratch << key;
157 }
158
159 void Next();
160
161 template<typename K> bool GetKey(K& key) {
162 try {
163 SpanReader ssKey{GetKeyImpl()};
164 ssKey >> key;
165 } catch (const std::exception&) {
166 return false;
167 }
168 return true;
169 }
170
171 template<typename V> bool GetValue(V& value) {
172 try {
173 ScopedDataStreamUsage scoped_scratch{m_scratch};
176 m_scratch >> value;
177 } catch (const std::exception&) {
178 return false;
179 }
180 return true;
181 }
182};
183
184struct LevelDBContext;
185
187{
189private:
191 std::unique_ptr<LevelDBContext> m_db_context;
192
194 std::string m_name;
195
198
200 inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
201
202 std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
203 bool ExistsImpl(std::span<const std::byte> key) const;
204 size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
205 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
206
207public:
208 CDBWrapper(const DBParams& params);
209 ~CDBWrapper();
210
211 CDBWrapper(const CDBWrapper&) = delete;
212 CDBWrapper& operator=(const CDBWrapper&) = delete;
213
214 template <typename K, typename V>
215 bool Read(const K& key, V& value) const
216 {
217 DataStream ssKey{};
219 ssKey << key;
220 std::optional<std::string> strValue{ReadImpl(ssKey)};
221 if (!strValue) {
222 return false;
223 }
224 try {
225 std::span ssValue{MakeWritableByteSpan(*strValue)};
226 m_obfuscation(ssValue);
227 SpanReader{ssValue} >> value;
228 } catch (const std::exception&) {
229 return false;
230 }
231 return true;
232 }
233
234 template <typename K, typename V>
235 void Write(const K& key, const V& value, bool fSync = false)
236 {
237 CDBBatch batch(*this);
238 batch.Write(key, value);
239 WriteBatch(batch, fSync);
240 }
241
242 template <typename K>
243 bool Exists(const K& key) const
244 {
245 DataStream ssKey{};
247 ssKey << key;
248 return ExistsImpl(ssKey);
249 }
250
251 template <typename K>
252 void Erase(const K& key, bool fSync = false)
253 {
254 CDBBatch batch(*this);
255 batch.Erase(key);
256 WriteBatch(batch, fSync);
257 }
258
259 void WriteBatch(CDBBatch& batch, bool fSync = false);
260
261 // Get an estimate of LevelDB memory usage (in bytes).
262 size_t DynamicMemoryUsage() const;
263
265
269 bool IsEmpty();
270
271 template<typename K>
272 size_t EstimateSize(const K& key_begin, const K& key_end) const
273 {
274 DataStream ssKey1{}, ssKey2{};
276 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
277 ssKey1 << key_begin;
278 ssKey2 << key_end;
279 return EstimateSizeImpl(ssKey1, ssKey2);
280 }
281};
282
283#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:83
void Erase(const K &key)
Definition: dbwrapper.h:116
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:90
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:107
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:92
size_t ApproximateSize() const
Definition: dbwrapper.cpp:192
const CDBWrapper & parent
Definition: dbwrapper.h:87
DataStream m_value_scratch
Definition: dbwrapper.h:93
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:367
bool GetValue(V &value)
Definition: dbwrapper.h:171
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:133
void SeekImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:378
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:384
bool GetKey(K &key)
Definition: dbwrapper.h:161
DataStream m_scratch
Definition: dbwrapper.h:134
void Seek(const K &key)
Definition: dbwrapper.h:153
const CDBWrapper & parent
Definition: dbwrapper.h:132
bool Valid() const
Definition: dbwrapper.cpp:397
void SeekToFirst()
Definition: dbwrapper.cpp:398
void Next()
Definition: dbwrapper.cpp:399
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:391
CDBWrapper(const CDBWrapper &)=delete
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:315
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:344
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:304
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:215
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:373
std::string m_name
the name of this database
Definition: dbwrapper.h:194
bool Exists(const K &key) const
Definition: dbwrapper.h:243
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:220
void Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:252
void WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:288
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:329
void Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:235
Obfuscation m_obfuscation
optional XOR-obfuscation of the database
Definition: dbwrapper.h:197
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:191
CDBWrapper & operator=(const CDBWrapper &)=delete
static const std::string OBFUSCATION_KEY
obfuscation key storage key, null-prefixed to avoid collisions
Definition: dbwrapper.h:200
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:205
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:354
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:272
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:63
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:27
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:39
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE
Definition: dbwrapper.h:28
static const size_t DBWRAPPER_MAX_FILE_SIZE
Definition: dbwrapper.h:29
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:401
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:403
Definition: common.h:30
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
User-controlled performance and debug options.
Definition: dbwrapper.h:32
bool force_compact
Compact database on startup.
Definition: dbwrapper.h:34
Application-specific storage settings.
Definition: dbwrapper.h:38
DBOptions options
Passed-through options.
Definition: dbwrapper.h:51
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition: dbwrapper.h:49
size_t max_file_size
Maximum LevelDB SST file size.
Definition: dbwrapper.h:57
bool wipe_data
If true, remove all existing data.
Definition: dbwrapper.h:46
leveldb::Env * testing_env
If non-null, use this as the leveldb::Env instead of the default.
Definition: dbwrapper.h:54
size_t cache_bytes
Configures various leveldb cache settings.
Definition: dbwrapper.h:42
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition: dbwrapper.h:40
bool memory_only
If true, use leveldb's memory environment.
Definition: dbwrapper.h:44