Merge pull request #6599
[bitcoinplatinum.git] / src / leveldbwrapper.h
blobc65e842704a1142ae95ba5b02604a2befc96eeff
1 // Copyright (c) 2012-2014 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.
5 #ifndef BITCOIN_LEVELDBWRAPPER_H
6 #define BITCOIN_LEVELDBWRAPPER_H
8 #include "clientversion.h"
9 #include "serialize.h"
10 #include "streams.h"
11 #include "util.h"
12 #include "version.h"
14 #include <boost/filesystem/path.hpp>
16 #include <leveldb/db.h>
17 #include <leveldb/write_batch.h>
19 class leveldb_error : public std::runtime_error
21 public:
22 leveldb_error(const std::string& msg) : std::runtime_error(msg) {}
25 void HandleError(const leveldb::Status& status) throw(leveldb_error);
27 /** Batch of changes queued to be written to a CLevelDBWrapper */
28 class CLevelDBBatch
30 friend class CLevelDBWrapper;
32 private:
33 leveldb::WriteBatch batch;
35 public:
36 template <typename K, typename V>
37 void Write(const K& key, const V& value)
39 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
40 ssKey.reserve(ssKey.GetSerializeSize(key));
41 ssKey << key;
42 leveldb::Slice slKey(&ssKey[0], ssKey.size());
44 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
45 ssValue.reserve(ssValue.GetSerializeSize(value));
46 ssValue << value;
47 leveldb::Slice slValue(&ssValue[0], ssValue.size());
49 batch.Put(slKey, slValue);
52 template <typename K>
53 void Erase(const K& key)
55 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
56 ssKey.reserve(ssKey.GetSerializeSize(key));
57 ssKey << key;
58 leveldb::Slice slKey(&ssKey[0], ssKey.size());
60 batch.Delete(slKey);
64 class CLevelDBWrapper
66 private:
67 //! custom environment this database is using (may be NULL in case of default environment)
68 leveldb::Env* penv;
70 //! database options used
71 leveldb::Options options;
73 //! options used when reading from the database
74 leveldb::ReadOptions readoptions;
76 //! options used when iterating over values of the database
77 leveldb::ReadOptions iteroptions;
79 //! options used when writing to the database
80 leveldb::WriteOptions writeoptions;
82 //! options used when sync writing to the database
83 leveldb::WriteOptions syncoptions;
85 //! the database itself
86 leveldb::DB* pdb;
88 public:
89 CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
90 ~CLevelDBWrapper();
92 template <typename K, typename V>
93 bool Read(const K& key, V& value) const throw(leveldb_error)
95 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
96 ssKey.reserve(ssKey.GetSerializeSize(key));
97 ssKey << key;
98 leveldb::Slice slKey(&ssKey[0], ssKey.size());
100 std::string strValue;
101 leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
102 if (!status.ok()) {
103 if (status.IsNotFound())
104 return false;
105 LogPrintf("LevelDB read failure: %s\n", status.ToString());
106 HandleError(status);
108 try {
109 CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
110 ssValue >> value;
111 } catch (const std::exception&) {
112 return false;
114 return true;
117 template <typename K, typename V>
118 bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error)
120 CLevelDBBatch batch;
121 batch.Write(key, value);
122 return WriteBatch(batch, fSync);
125 template <typename K>
126 bool Exists(const K& key) const throw(leveldb_error)
128 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
129 ssKey.reserve(ssKey.GetSerializeSize(key));
130 ssKey << key;
131 leveldb::Slice slKey(&ssKey[0], ssKey.size());
133 std::string strValue;
134 leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
135 if (!status.ok()) {
136 if (status.IsNotFound())
137 return false;
138 LogPrintf("LevelDB read failure: %s\n", status.ToString());
139 HandleError(status);
141 return true;
144 template <typename K>
145 bool Erase(const K& key, bool fSync = false) throw(leveldb_error)
147 CLevelDBBatch batch;
148 batch.Erase(key);
149 return WriteBatch(batch, fSync);
152 bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error);
154 // not available for LevelDB; provide for compatibility with BDB
155 bool Flush()
157 return true;
160 bool Sync() throw(leveldb_error)
162 CLevelDBBatch batch;
163 return WriteBatch(batch, true);
166 // not exactly clean encapsulation, but it's easiest for now
167 leveldb::Iterator* NewIterator()
169 return pdb->NewIterator(iteroptions);
173 #endif // BITCOIN_LEVELDBWRAPPER_H