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