]> Git Repo - VerusCoin.git/blame - src/dbwrapper.h
Remove debug outs
[VerusCoin.git] / src / dbwrapper.h
CommitLineData
f914f1a7 1// Copyright (c) 2012-2014 The Bitcoin Core developers
fa94b9d5 2// Distributed under the MIT software license, see the accompanying
bc909a7a 3// file COPYING or https://www.opensource.org/licenses/mit-license.php .
b64187d0 4
e3da7a57
JG
5#ifndef BITCOIN_DBWRAPPER_H
6#define BITCOIN_DBWRAPPER_H
43b7905e 7
71697f97 8#include "clientversion.h"
43b7905e 9#include "serialize.h"
fa736190 10#include "streams.h"
881a85a2 11#include "util.h"
51ed9ec9 12#include "version.h"
43b7905e 13
51ed9ec9 14#include <boost/filesystem/path.hpp>
611116d4 15
43b7905e
PW
16#include <leveldb/db.h>
17#include <leveldb/write_batch.h>
18
87a5975c
PW
19static const size_t DBWRAPPER_PREALLOC_KEY_SIZE = 64;
20static const size_t DBWRAPPER_PREALLOC_VALUE_SIZE = 1024;
21
f345c41e 22class dbwrapper_error : public std::runtime_error
421218d3
PW
23{
24public:
f345c41e 25 dbwrapper_error(const std::string& msg) : std::runtime_error(msg) {}
421218d3
PW
26};
27
3923bcca
WL
28class CDBWrapper;
29
30/** These should be considered an implementation detail of the specific database.
31 */
32namespace dbwrapper_private {
33
34/** Handle database error by throwing dbwrapper_error exception.
35 */
ecd04e91 36void HandleError(const leveldb::Status& status);
421218d3 37
3923bcca 38};
809a429e 39
f345c41e
JG
40/** Batch of changes queued to be written to a CDBWrapper */
41class CDBBatch
43b7905e 42{
f345c41e 43 friend class CDBWrapper;
43b7905e
PW
44
45private:
809a429e 46 const CDBWrapper &parent;
43b7905e
PW
47 leveldb::WriteBatch batch;
48
49public:
809a429e 50 /**
56aa2568 51 * @param[in] _parent CDBWrapper that this batch is to be submitted to
809a429e 52 */
56aa2568 53 CDBBatch(const CDBWrapper &_parent) : parent(_parent) { };
809a429e 54
20e01b1a
PW
55 template <typename K, typename V>
56 void Write(const K& key, const V& value)
57 {
43b7905e 58 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
87a5975c 59 ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
43b7905e
PW
60 ssKey << key;
61 leveldb::Slice slKey(&ssKey[0], ssKey.size());
62
63 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
87a5975c 64 ssValue.reserve(DBWRAPPER_PREALLOC_VALUE_SIZE);
43b7905e
PW
65 ssValue << value;
66 leveldb::Slice slValue(&ssValue[0], ssValue.size());
67
68 batch.Put(slKey, slValue);
69 }
70
20e01b1a
PW
71 template <typename K>
72 void Erase(const K& key)
73 {
43b7905e 74 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
87a5975c 75 ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
43b7905e
PW
76 ssKey << key;
77 leveldb::Slice slKey(&ssKey[0], ssKey.size());
78
79 batch.Delete(slKey);
80 }
81};
7249ee6d 82
f345c41e 83class CDBIterator
1ebf50b6
PW
84{
85private:
809a429e 86 const CDBWrapper &parent;
1ebf50b6
PW
87 leveldb::Iterator *piter;
88
89public:
0d9524ba
JB
90
91 /**
56aa2568
PJ
92 * @param[in] _parent Parent CDBWrapper instance.
93 * @param[in] _piter The original leveldb iterator.
0d9524ba 94 */
56aa2568
PJ
95 CDBIterator(const CDBWrapper &_parent, leveldb::Iterator *_piter) :
96 parent(_parent), piter(_piter) { };
f345c41e 97 ~CDBIterator();
1ebf50b6
PW
98
99 bool Valid();
43b7905e 100
1ebf50b6 101 void SeekToFirst();
9feb4b9e 102 void SeekToLast();
1ebf50b6
PW
103
104 template<typename K> void Seek(const K& key) {
105 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
a8e5ae92 106 ssKey.reserve(GetSerializeSize(ssKey, key));
1ebf50b6
PW
107 ssKey << key;
108 leveldb::Slice slKey(&ssKey[0], ssKey.size());
109 piter->Seek(slKey);
110 }
111
112 void Next();
9feb4b9e 113 void Prev();
1ebf50b6
PW
114
115 template<typename K> bool GetKey(K& key) {
116 leveldb::Slice slKey = piter->key();
117 try {
118 CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
119 ssKey >> key;
120 } catch(std::exception &e) {
121 return false;
122 }
123 return true;
124 }
125
126 unsigned int GetKeySize() {
127 return piter->key().size();
128 }
129
130 template<typename V> bool GetValue(V& value) {
131 leveldb::Slice slValue = piter->value();
132 try {
133 CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
134 ssValue >> value;
135 } catch(std::exception &e) {
136 return false;
137 }
138 return true;
139 }
140
141 unsigned int GetValueSize() {
142 return piter->value().size();
143 }
144
145};
7249ee6d 146
f345c41e 147class CDBWrapper
43b7905e
PW
148{
149private:
fa94b9d5 150 //! custom environment this database is using (may be NULL in case of default environment)
20e01b1a 151 leveldb::Env* penv;
43b7905e 152
fa94b9d5 153 //! database options used
43b7905e
PW
154 leveldb::Options options;
155
fa94b9d5 156 //! options used when reading from the database
43b7905e
PW
157 leveldb::ReadOptions readoptions;
158
fa94b9d5 159 //! options used when iterating over values of the database
43b7905e
PW
160 leveldb::ReadOptions iteroptions;
161
fa94b9d5 162 //! options used when writing to the database
43b7905e
PW
163 leveldb::WriteOptions writeoptions;
164
fa94b9d5 165 //! options used when sync writing to the database
43b7905e
PW
166 leveldb::WriteOptions syncoptions;
167
fa94b9d5 168 //! the database itself
20e01b1a 169 leveldb::DB* pdb;
43b7905e
PW
170
171public:
0d81464b
JB
172 /**
173 * @param[in] path Location in the filesystem where leveldb data will be stored.
174 * @param[in] nCacheSize Configures various leveldb cache settings.
175 * @param[in] fMemory If true, use leveldb's memory environment.
176 * @param[in] fWipe If true, remove all existing data.
177 */
9feb4b9e 178 CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool compression = false, int maxOpenFiles = 64);
f345c41e 179 ~CDBWrapper();
43b7905e 180
20e01b1a 181 template <typename K, typename V>
ecd04e91 182 bool Read(const K& key, V& value) const
20e01b1a 183 {
43b7905e 184 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
87a5975c 185 ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
43b7905e
PW
186 ssKey << key;
187 leveldb::Slice slKey(&ssKey[0], ssKey.size());
188
189 std::string strValue;
190 leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
191 if (!status.ok()) {
192 if (status.IsNotFound())
193 return false;
79d06dc6 194 LogPrintf("LevelDB read failure: %s\n", status.ToString());
3923bcca 195 dbwrapper_private::HandleError(status);
43b7905e
PW
196 }
197 try {
198 CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
199 ssValue >> value;
20e01b1a 200 } catch (const std::exception&) {
43b7905e
PW
201 return false;
202 }
203 return true;
204 }
205
20e01b1a 206 template <typename K, typename V>
ecd04e91 207 bool Write(const K& key, const V& value, bool fSync = false)
20e01b1a 208 {
809a429e 209 CDBBatch batch(*this);
43b7905e
PW
210 batch.Write(key, value);
211 return WriteBatch(batch, fSync);
212 }
213
20e01b1a 214 template <typename K>
ecd04e91 215 bool Exists(const K& key) const
20e01b1a 216 {
43b7905e 217 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
87a5975c 218 ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
43b7905e
PW
219 ssKey << key;
220 leveldb::Slice slKey(&ssKey[0], ssKey.size());
221
222 std::string strValue;
223 leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
224 if (!status.ok()) {
225 if (status.IsNotFound())
226 return false;
79d06dc6 227 LogPrintf("LevelDB read failure: %s\n", status.ToString());
3923bcca 228 dbwrapper_private::HandleError(status);
43b7905e
PW
229 }
230 return true;
231 }
232
20e01b1a 233 template <typename K>
ecd04e91 234 bool Erase(const K& key, bool fSync = false)
20e01b1a 235 {
809a429e 236 CDBBatch batch(*this);
43b7905e
PW
237 batch.Erase(key);
238 return WriteBatch(batch, fSync);
239 }
240
f345c41e 241 bool WriteBatch(CDBBatch& batch, bool fSync = false);
43b7905e
PW
242
243 // not available for LevelDB; provide for compatibility with BDB
20e01b1a
PW
244 bool Flush()
245 {
43b7905e
PW
246 return true;
247 }
248
ecd04e91 249 bool Sync()
20e01b1a 250 {
809a429e 251 CDBBatch batch(*this);
43b7905e
PW
252 return WriteBatch(batch, true);
253 }
254
f345c41e 255 CDBIterator *NewIterator()
1ebf50b6 256 {
809a429e 257 return new CDBIterator(*this, pdb->NewIterator(iteroptions));
0d9524ba 258 }
0d81464b
JB
259
260 /**
261 * Return true if the database managed by this class contains no entries.
262 */
263 bool IsEmpty();
43b7905e
PW
264};
265
e3da7a57 266#endif // BITCOIN_DBWRAPPER_H
0d81464b 267
This page took 0.264432 seconds and 4 git commands to generate.