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
23static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
24static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
25static const size_t DBWRAPPER_MAX_FILE_SIZE{32_MiB};
26
28struct DBOptions {
30 bool force_compact = false;
31};
32
34struct DBParams {
36 fs::path path;
40 bool memory_only = false;
42 bool wipe_data = false;
45 bool obfuscate = false;
48};
49
50class dbwrapper_error : public std::runtime_error
51{
52public:
53 explicit dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
54};
55
56class CDBWrapper;
57
60namespace dbwrapper_private {
61
67}; // namespace dbwrapper_private
68
69bool DestroyDB(const std::string& path_str);
70
73{
74 friend class CDBWrapper;
75
76private:
78
79 struct WriteBatchImpl;
80 const std::unique_ptr<WriteBatchImpl> m_impl_batch;
81
84
85 void WriteImpl(std::span<const std::byte> key, DataStream& value);
86 void EraseImpl(std::span<const std::byte> key);
87
88public:
92 explicit CDBBatch(const CDBWrapper& _parent);
94 void Clear();
95
96 template <typename K, typename V>
97 void Write(const K& key, const V& value)
98 {
99 ScopedDataStreamUsage scoped_key{m_key_scratch}, scoped_value{m_value_scratch};
100 m_key_scratch << key;
101 m_value_scratch << value;
103 }
104
105 template <typename K>
106 void Erase(const K& key)
107 {
109 m_key_scratch << key;
111 }
112
113 size_t ApproximateSize() const;
114};
115
117{
118public:
119 struct IteratorImpl;
120
121private:
123 const std::unique_ptr<IteratorImpl> m_impl_iter;
125
126 void SeekImpl(std::span<const std::byte> key);
127 std::span<const std::byte> GetKeyImpl() const;
128 std::span<const std::byte> GetValueImpl() const;
129
130public:
131
136 CDBIterator(const CDBWrapper& _parent, std::unique_ptr<IteratorImpl> _piter);
138
139 bool Valid() const;
140
141 void SeekToFirst();
142
143 template<typename K> void Seek(const K& key) {
144 ScopedDataStreamUsage scoped_scratch{m_scratch};
145 m_scratch << key;
147 }
148
149 void Next();
150
151 template<typename K> bool GetKey(K& key) {
152 try {
153 SpanReader ssKey{GetKeyImpl()};
154 ssKey >> key;
155 } catch (const std::exception&) {
156 return false;
157 }
158 return true;
159 }
160
161 template<typename V> bool GetValue(V& value) {
162 try {
163 ScopedDataStreamUsage scoped_scratch{m_scratch};
166 m_scratch >> value;
167 } catch (const std::exception&) {
168 return false;
169 }
170 return true;
171 }
172};
173
174struct LevelDBContext;
175
177{
179private:
181 std::unique_ptr<LevelDBContext> m_db_context;
182
184 std::string m_name;
185
188
190 inline static const std::string OBFUSCATION_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
191
192 std::optional<std::string> ReadImpl(std::span<const std::byte> key) const;
193 bool ExistsImpl(std::span<const std::byte> key) const;
194 size_t EstimateSizeImpl(std::span<const std::byte> key1, std::span<const std::byte> key2) const;
195 auto& DBContext() const LIFETIMEBOUND { return *Assert(m_db_context); }
196
197public:
198 CDBWrapper(const DBParams& params);
199 ~CDBWrapper();
200
201 CDBWrapper(const CDBWrapper&) = delete;
202 CDBWrapper& operator=(const CDBWrapper&) = delete;
203
204 template <typename K, typename V>
205 bool Read(const K& key, V& value) const
206 {
207 DataStream ssKey{};
209 ssKey << key;
210 std::optional<std::string> strValue{ReadImpl(ssKey)};
211 if (!strValue) {
212 return false;
213 }
214 try {
215 std::span ssValue{MakeWritableByteSpan(*strValue)};
216 m_obfuscation(ssValue);
217 SpanReader{ssValue} >> value;
218 } catch (const std::exception&) {
219 return false;
220 }
221 return true;
222 }
223
224 template <typename K, typename V>
225 void Write(const K& key, const V& value, bool fSync = false)
226 {
227 CDBBatch batch(*this);
228 batch.Write(key, value);
229 WriteBatch(batch, fSync);
230 }
231
232 template <typename K>
233 bool Exists(const K& key) const
234 {
235 DataStream ssKey{};
237 ssKey << key;
238 return ExistsImpl(ssKey);
239 }
240
241 template <typename K>
242 void Erase(const K& key, bool fSync = false)
243 {
244 CDBBatch batch(*this);
245 batch.Erase(key);
246 WriteBatch(batch, fSync);
247 }
248
249 void WriteBatch(CDBBatch& batch, bool fSync = false);
250
251 // Get an estimate of LevelDB memory usage (in bytes).
252 size_t DynamicMemoryUsage() const;
253
255
259 bool IsEmpty();
260
261 template<typename K>
262 size_t EstimateSize(const K& key_begin, const K& key_end) const
263 {
264 DataStream ssKey1{}, ssKey2{};
266 ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
267 ssKey1 << key_begin;
268 ssKey2 << key_end;
269 return EstimateSizeImpl(ssKey1, ssKey2);
270 }
271};
272
273#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:73
void Erase(const K &key)
Definition: dbwrapper.h:106
const std::unique_ptr< WriteBatchImpl > m_impl_batch
Definition: dbwrapper.h:80
void WriteImpl(std::span< const std::byte > key, DataStream &value)
Definition: dbwrapper.cpp:180
void Write(const K &key, const V &value)
Definition: dbwrapper.h:97
void EraseImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:188
void Clear()
Definition: dbwrapper.cpp:173
CDBBatch(const CDBWrapper &_parent)
Definition: dbwrapper.cpp:162
DataStream m_key_scratch
Definition: dbwrapper.h:82
size_t ApproximateSize() const
Definition: dbwrapper.cpp:194
const CDBWrapper & parent
Definition: dbwrapper.h:77
DataStream m_value_scratch
Definition: dbwrapper.h:83
CDBIterator(const CDBWrapper &_parent, std::unique_ptr< IteratorImpl > _piter)
Definition: dbwrapper.cpp:362
bool GetValue(V &value)
Definition: dbwrapper.h:161
const std::unique_ptr< IteratorImpl > m_impl_iter
Definition: dbwrapper.h:123
void SeekImpl(std::span< const std::byte > key)
Definition: dbwrapper.cpp:373
std::span< const std::byte > GetKeyImpl() const
Definition: dbwrapper.cpp:379
bool GetKey(K &key)
Definition: dbwrapper.h:151
DataStream m_scratch
Definition: dbwrapper.h:124
void Seek(const K &key)
Definition: dbwrapper.h:143
const CDBWrapper & parent
Definition: dbwrapper.h:122
bool Valid() const
Definition: dbwrapper.cpp:392
void SeekToFirst()
Definition: dbwrapper.cpp:393
void Next()
Definition: dbwrapper.cpp:394
std::span< const std::byte > GetValueImpl() const
Definition: dbwrapper.cpp:386
CDBWrapper(const CDBWrapper &)=delete
std::optional< std::string > ReadImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:310
size_t EstimateSizeImpl(std::span< const std::byte > key1, std::span< const std::byte > key2) const
Definition: dbwrapper.cpp:339
size_t DynamicMemoryUsage() const
Definition: dbwrapper.cpp:299
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:205
CDBIterator * NewIterator()
Definition: dbwrapper.cpp:368
std::string m_name
the name of this database
Definition: dbwrapper.h:184
bool Exists(const K &key) const
Definition: dbwrapper.h:233
CDBWrapper(const DBParams &params)
Definition: dbwrapper.cpp:222
void Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:242
void WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:283
bool ExistsImpl(std::span< const std::byte > key) const
Definition: dbwrapper.cpp:324
void Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:225
Obfuscation m_obfuscation
optional XOR-obfuscation of the database
Definition: dbwrapper.h:187
std::unique_ptr< LevelDBContext > m_db_context
holds all leveldb-specific fields of this class
Definition: dbwrapper.h:181
CDBWrapper & operator=(const CDBWrapper &)=delete
static const std::string OBFUSCATION_KEY
obfuscation key storage key, null-prefixed to avoid collisions
Definition: dbwrapper.h:190
auto & DBContext() const LIFETIMEBOUND
Definition: dbwrapper.h:195
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:349
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:262
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:53
static const size_t DBWRAPPER_PREALLOC_KEY_SIZE
Definition: dbwrapper.h:23
bool DestroyDB(const std::string &path_str)
Definition: dbwrapper.cpp:40
static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE
Definition: dbwrapper.h:24
static const size_t DBWRAPPER_MAX_FILE_SIZE
Definition: dbwrapper.h:25
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:396
const Obfuscation & GetObfuscation(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
Definition: dbwrapper.cpp:398
Definition: common.h:30
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
User-controlled performance and debug options.
Definition: dbwrapper.h:28
bool force_compact
Compact database on startup.
Definition: dbwrapper.h:30
Application-specific storage settings.
Definition: dbwrapper.h:34
DBOptions options
Passed-through options.
Definition: dbwrapper.h:47
bool obfuscate
If true, store data obfuscated via simple XOR.
Definition: dbwrapper.h:45
bool wipe_data
If true, remove all existing data.
Definition: dbwrapper.h:42
size_t cache_bytes
Configures various leveldb cache settings.
Definition: dbwrapper.h:38
fs::path path
Location in the filesystem where leveldb data will be stored.
Definition: dbwrapper.h:36
bool memory_only
If true, use leveldb's memory environment.
Definition: dbwrapper.h:40