Anoncoin  0.9.4
P2P Digital Currency
leveldbwrapper.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2013 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef ANONCOIN_LEVELDBWRAPPER_H
7 #define ANONCOIN_LEVELDBWRAPPER_H
8 
9 #include "clientversion.h"
10 #include "serialize.h"
11 #include "util.h"
12 #include "version.h"
13 
14 #include <boost/filesystem/path.hpp>
15 #include <leveldb/db.h>
16 #include <leveldb/write_batch.h>
17 
18 class leveldb_error : public std::runtime_error
19 {
20 public:
21  leveldb_error(const std::string &msg) : std::runtime_error(msg) {}
22 };
23 
24 void HandleError(const leveldb::Status &status) throw(leveldb_error);
25 
26 // Batch of changes queued to be written to a CLevelDBWrapper
28 {
29  friend class CLevelDBWrapper;
30 
31 private:
32  leveldb::WriteBatch batch;
33 
34 public:
35  template<typename K, typename V> void Write(const K& key, const V& value) {
36  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
37  ssKey.reserve(ssKey.GetSerializeSize(key));
38  ssKey << key;
39  leveldb::Slice slKey(&ssKey[0], ssKey.size());
40 
41  CDataStream ssValue(SER_DISK, CLIENT_VERSION);
42  ssValue.reserve(ssValue.GetSerializeSize(value));
43  ssValue << value;
44  leveldb::Slice slValue(&ssValue[0], ssValue.size());
45 
46  batch.Put(slKey, slValue);
47  }
48 
49  template<typename K> void Erase(const K& key) {
50  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
51  ssKey.reserve(ssKey.GetSerializeSize(key));
52  ssKey << key;
53  leveldb::Slice slKey(&ssKey[0], ssKey.size());
54 
55  batch.Delete(slKey);
56  }
57 };
58 
60 {
61 private:
62  // custom environment this database is using (may be NULL in case of default environment)
63  leveldb::Env *penv;
64 
65  // database options used
66  leveldb::Options options;
67 
68  // options used when reading from the database
69  leveldb::ReadOptions readoptions;
70 
71  // options used when iterating over values of the database
72  leveldb::ReadOptions iteroptions;
73 
74  // options used when writing to the database
75  leveldb::WriteOptions writeoptions;
76 
77  // options used when sync writing to the database
78  leveldb::WriteOptions syncoptions;
79 
80  // the database itself
81  leveldb::DB *pdb;
82 
83 public:
84  CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false, bool fWipe = false);
86 
87  template<typename K, typename V> bool Read(const K& key, V& value) throw(leveldb_error) {
88  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
89  ssKey.reserve(ssKey.GetSerializeSize(key));
90  ssKey << key;
91  leveldb::Slice slKey(&ssKey[0], ssKey.size());
92 
93  std::string strValue;
94  leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
95  if (!status.ok()) {
96  if (status.IsNotFound())
97  return false;
98  LogPrintf("LevelDB read failure: %s\n", status.ToString().c_str());
99  HandleError(status);
100  }
101  try {
102  CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION);
103  ssValue >> value;
104  } catch(std::exception &e) {
105  return false;
106  }
107  return true;
108  }
109 
110  template<typename K, typename V> bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) {
111  CLevelDBBatch batch;
112  batch.Write(key, value);
113  return WriteBatch(batch, fSync);
114  }
115 
116  template<typename K> bool Exists(const K& key) throw(leveldb_error) {
117  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
118  ssKey.reserve(ssKey.GetSerializeSize(key));
119  ssKey << key;
120  leveldb::Slice slKey(&ssKey[0], ssKey.size());
121 
122  std::string strValue;
123  leveldb::Status status = pdb->Get(readoptions, slKey, &strValue);
124  if (!status.ok()) {
125  if (status.IsNotFound())
126  return false;
127  LogPrintf("LevelDB read failure: %s\n", status.ToString().c_str());
128  HandleError(status);
129  }
130  return true;
131  }
132 
133  template<typename K> bool Erase(const K& key, bool fSync = false) throw(leveldb_error) {
134  CLevelDBBatch batch;
135  batch.Erase(key);
136  return WriteBatch(batch, fSync);
137  }
138 
139  bool WriteBatch(CLevelDBBatch &batch, bool fSync = false) throw(leveldb_error);
140 
141  // not available for LevelDB; provide for compatibility with BDB
142  bool Flush() {
143  return true;
144  }
145 
146  bool Sync() throw(leveldb_error) {
147  CLevelDBBatch batch;
148  return WriteBatch(batch, true);
149  }
150 
151  // not exactly clean encapsulation, but it's easiest for now
152  leveldb::Iterator *NewIterator() {
153  return pdb->NewIterator(iteroptions);
154  }
155 };
156 
157 #endif // ANONCOIN_LEVELDBWRAPPER_H
bool Erase(const K &key, bool fSync=false)
leveldb::Env * penv
bool Write(const K &key, const V &value, bool fSync=false)
Double ended buffer combining vector and stream-like interfaces.
Definition: serialize.h:848
leveldb::WriteOptions syncoptions
leveldb::DB * pdb
void Write(const K &key, const V &value)
bool Exists(const K &key)
leveldb::WriteBatch batch
#define LogPrintf(...)
Definition: util.h:118
CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory=false, bool fWipe=false)
leveldb::WriteOptions writeoptions
size_type size() const
Definition: serialize.h:937
leveldb::ReadOptions iteroptions
bool Read(const K &key, V &value)
bool WriteBatch(CLevelDBBatch &batch, bool fSync=false)
leveldb::Options options
void reserve(size_type n)
Definition: serialize.h:940
void Erase(const K &key)
unsigned int GetSerializeSize(const T &obj)
Definition: serialize.h:1111
leveldb_error(const std::string &msg)
void HandleError(const leveldb::Status &status)
leveldb::Iterator * NewIterator()
leveldb::ReadOptions readoptions