]> Git Repo - VerusCoin.git/blame - src/leveldbwrapper.h
Auto merge of #2704 - bitcartel:fix_qa_shieldcoinbase_hang, r=str4d
[VerusCoin.git] / src / leveldbwrapper.h
CommitLineData
f914f1a7 1// Copyright (c) 2012-2014 The Bitcoin Core developers
fa94b9d5 2// Distributed under the MIT software license, see the accompanying
43b7905e 3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
b64187d0
BD
4
5#ifndef BITCOIN_LEVELDBWRAPPER_H
6#define BITCOIN_LEVELDBWRAPPER_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
421218d3
PW
19class leveldb_error : public std::runtime_error
20{
21public:
20e01b1a 22 leveldb_error(const std::string& msg) : std::runtime_error(msg) {}
421218d3
PW
23};
24
ecd04e91 25void HandleError(const leveldb::Status& status);
421218d3 26
fa94b9d5 27/** Batch of changes queued to be written to a CLevelDBWrapper */
43b7905e
PW
28class CLevelDBBatch
29{
b64187d0 30 friend class CLevelDBWrapper;
43b7905e
PW
31
32private:
33 leveldb::WriteBatch batch;
34
35public:
20e01b1a
PW
36 template <typename K, typename V>
37 void Write(const K& key, const V& value)
38 {
43b7905e
PW
39 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
40 ssKey.reserve(ssKey.GetSerializeSize(key));
41 ssKey << key;
42 leveldb::Slice slKey(&ssKey[0], ssKey.size());
43
44 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
45 ssValue.reserve(ssValue.GetSerializeSize(value));
46 ssValue << value;
47 leveldb::Slice slValue(&ssValue[0], ssValue.size());
48
49 batch.Put(slKey, slValue);
50 }
51
20e01b1a
PW
52 template <typename K>
53 void Erase(const K& key)
54 {
43b7905e
PW
55 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
56 ssKey.reserve(ssKey.GetSerializeSize(key));
57 ssKey << key;
58 leveldb::Slice slKey(&ssKey[0], ssKey.size());
59
60 batch.Delete(slKey);
61 }
62};
63
b64187d0 64class CLevelDBWrapper
43b7905e
PW
65{
66private:
fa94b9d5 67 //! custom environment this database is using (may be NULL in case of default environment)
20e01b1a 68 leveldb::Env* penv;
43b7905e 69
fa94b9d5 70 //! database options used
43b7905e
PW
71 leveldb::Options options;
72
fa94b9d5 73 //! options used when reading from the database
43b7905e
PW
74 leveldb::ReadOptions readoptions;
75
fa94b9d5 76 //! options used when iterating over values of the database
43b7905e
PW
77 leveldb::ReadOptions iteroptions;
78
fa94b9d5 79 //! options used when writing to the database
43b7905e
PW
80 leveldb::WriteOptions writeoptions;
81
fa94b9d5 82 //! options used when sync writing to the database
43b7905e
PW
83 leveldb::WriteOptions syncoptions;
84
fa94b9d5 85 //! the database itself
20e01b1a 86 leveldb::DB* pdb;
43b7905e
PW
87
88public:
20e01b1a 89 CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
b64187d0 90 ~CLevelDBWrapper();
43b7905e 91
20e01b1a 92 template <typename K, typename V>
ecd04e91 93 bool Read(const K& key, V& value) const
20e01b1a 94 {
43b7905e
PW
95 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
96 ssKey.reserve(ssKey.GetSerializeSize(key));
97 ssKey << key;
98 leveldb::Slice slKey(&ssKey[0], ssKey.size());
99
100 std::string strValue;
101 leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
102 if (!status.ok()) {
103 if (status.IsNotFound())
104 return false;
79d06dc6 105 LogPrintf("LevelDB read failure: %s\n", status.ToString());
421218d3 106 HandleError(status);
43b7905e
PW
107 }
108 try {
109 CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
110 ssValue >> value;
20e01b1a 111 } catch (const std::exception&) {
43b7905e
PW
112 return false;
113 }
114 return true;
115 }
116
20e01b1a 117 template <typename K, typename V>
ecd04e91 118 bool Write(const K& key, const V& value, bool fSync = false)
20e01b1a 119 {
43b7905e
PW
120 CLevelDBBatch batch;
121 batch.Write(key, value);
122 return WriteBatch(batch, fSync);
123 }
124
20e01b1a 125 template <typename K>
ecd04e91 126 bool Exists(const K& key) const
20e01b1a 127 {
43b7905e
PW
128 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
129 ssKey.reserve(ssKey.GetSerializeSize(key));
130 ssKey << key;
131 leveldb::Slice slKey(&ssKey[0], ssKey.size());
132
133 std::string strValue;
134 leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
135 if (!status.ok()) {
136 if (status.IsNotFound())
137 return false;
79d06dc6 138 LogPrintf("LevelDB read failure: %s\n", status.ToString());
421218d3 139 HandleError(status);
43b7905e
PW
140 }
141 return true;
142 }
143
20e01b1a 144 template <typename K>
ecd04e91 145 bool Erase(const K& key, bool fSync = false)
20e01b1a 146 {
43b7905e
PW
147 CLevelDBBatch batch;
148 batch.Erase(key);
149 return WriteBatch(batch, fSync);
150 }
151
ecd04e91 152 bool WriteBatch(CLevelDBBatch& batch, bool fSync = false);
43b7905e
PW
153
154 // not available for LevelDB; provide for compatibility with BDB
20e01b1a
PW
155 bool Flush()
156 {
43b7905e
PW
157 return true;
158 }
159
ecd04e91 160 bool Sync()
20e01b1a 161 {
43b7905e
PW
162 CLevelDBBatch batch;
163 return WriteBatch(batch, true);
164 }
165
166 // not exactly clean encapsulation, but it's easiest for now
20e01b1a
PW
167 leveldb::Iterator* NewIterator()
168 {
43b7905e
PW
169 return pdb->NewIterator(iteroptions);
170 }
171};
172
b64187d0 173#endif // BITCOIN_LEVELDBWRAPPER_H
This page took 0.184251 seconds and 4 git commands to generate.