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