diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2012-09-03 19:05:30 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2012-10-20 23:08:56 +0200 |
commit | 43b7905e98d827df45e970dbaf5f08561ecc6cda (patch) | |
tree | a2f90a07dfd16e3a3ec1ae418e3f65a2f2177579 /src/leveldb.h | |
parent | 3ff3a2bd60a905d830de157390facde14aa0ffe3 (diff) |
LevelDB glue
Database-independent glue for supporting LevelDB databases.
Based on code from earlier commits by Mike Hearn in his leveldb
branch.
Diffstat (limited to 'src/leveldb.h')
-rw-r--r-- | src/leveldb.h | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/leveldb.h b/src/leveldb.h new file mode 100644 index 0000000000..28484dac9d --- /dev/null +++ b/src/leveldb.h @@ -0,0 +1,144 @@ +// Copyright (c) 2012 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_LEVELDB_H +#define BITCOIN_LEVELDB_H + +#include "serialize.h" + +#include <leveldb/db.h> +#include <leveldb/write_batch.h> + +#include <boost/filesystem/path.hpp> + +// Batch of changes queued to be written to a CLevelDB +class CLevelDBBatch +{ + friend class CLevelDB; + +private: + leveldb::WriteBatch batch; + +public: + template<typename K, typename V> void Write(const K& key, const V& value) { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(ssValue.GetSerializeSize(value)); + ssValue << value; + leveldb::Slice slValue(&ssValue[0], ssValue.size()); + + batch.Put(slKey, slValue); + } + + template<typename K> void Erase(const K& key) { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + batch.Delete(slKey); + } +}; + +class CLevelDB +{ +private: + // custom environment this database is using (may be NULL in case of default environment) + leveldb::Env *penv; + + // database options used + leveldb::Options options; + + // options used when reading from the database + leveldb::ReadOptions readoptions; + + // options used when iterating over values of the database + leveldb::ReadOptions iteroptions; + + // options used when writing to the database + leveldb::WriteOptions writeoptions; + + // options used when sync writing to the database + leveldb::WriteOptions syncoptions; + + // the database itself + leveldb::DB *pdb; + +public: + CLevelDB(const boost::filesystem::path &path); + ~CLevelDB(); + + template<typename K, typename V> bool Read(const K& key, V& value) { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + std::string strValue; + leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); + if (!status.ok()) { + if (status.IsNotFound()) + return false; + printf("LevelDB read failure: %s\n", status.ToString().c_str()); + } + try { + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + ssValue >> value; + } catch(std::exception &e) { + return false; + } + return true; + } + + template<typename K, typename V> bool Write(const K& key, const V& value, bool fSync = false) { + CLevelDBBatch batch; + batch.Write(key, value); + return WriteBatch(batch, fSync); + } + + template<typename K> bool Exists(const K& key) { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + ssKey.reserve(ssKey.GetSerializeSize(key)); + ssKey << key; + leveldb::Slice slKey(&ssKey[0], ssKey.size()); + + std::string strValue; + leveldb::Status status = pdb->Get(readoptions, slKey, &strValue); + if (!status.ok()) { + if (status.IsNotFound()) + return false; + printf("LevelDB read failure: %s\n", status.ToString().c_str()); + } + return true; + } + + template<typename K> bool Erase(const K& key, bool fSync = false) { + CLevelDBBatch batch; + batch.Erase(key); + return WriteBatch(batch, fSync); + } + + bool WriteBatch(CLevelDBBatch &batch, bool fSync = false); + + // not available for LevelDB; provide for compatibility with BDB + bool Flush() { + return true; + } + + bool Sync() { + CLevelDBBatch batch; + return WriteBatch(batch, true); + } + + // not exactly clean encapsulation, but it's easiest for now + leveldb::Iterator *NewIterator() { + return pdb->NewIterator(iteroptions); + } +}; + +#endif // BITCOIN_LEVELDB_H +
\ No newline at end of file |