]>
Commit | Line | Data |
---|---|---|
f914f1a7 | 1 | // Copyright (c) 2012-2014 The Bitcoin Core developers |
b4347f60 | 2 | // Distributed under the MIT software license, see the accompanying |
43b7905e PW |
3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | ||
b64187d0 | 5 | #include "leveldbwrapper.h" |
51ed9ec9 | 6 | |
43b7905e PW |
7 | #include "util.h" |
8 | ||
51ed9ec9 | 9 | #include <boost/filesystem.hpp> |
b4347f60 | 10 | |
43b7905e | 11 | #include <leveldb/cache.h> |
51ed9ec9 | 12 | #include <leveldb/env.h> |
43b7905e | 13 | #include <leveldb/filter_policy.h> |
eb12a14d | 14 | #include <memenv.h> |
0d81464b | 15 | #include <stdint.h> |
43b7905e | 16 | |
ecd04e91 | 17 | void HandleError(const leveldb::Status& status) |
20e01b1a | 18 | { |
421218d3 PW |
19 | if (status.ok()) |
20 | return; | |
7d9d134b | 21 | LogPrintf("%s\n", status.ToString()); |
421218d3 | 22 | if (status.IsCorruption()) |
f345c41e | 23 | throw dbwrapper_error("Database corrupted"); |
421218d3 | 24 | if (status.IsIOError()) |
f345c41e | 25 | throw dbwrapper_error("Database I/O error"); |
421218d3 | 26 | if (status.IsNotFound()) |
f345c41e JG |
27 | throw dbwrapper_error("Database entry missing"); |
28 | throw dbwrapper_error("Unknown database error"); | |
421218d3 PW |
29 | } |
30 | ||
20e01b1a PW |
31 | static leveldb::Options GetOptions(size_t nCacheSize) |
32 | { | |
43b7905e | 33 | leveldb::Options options; |
1c83b0a3 PW |
34 | options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); |
35 | options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously | |
43b7905e PW |
36 | options.filter_policy = leveldb::NewBloomFilterPolicy(10); |
37 | options.compression = leveldb::kNoCompression; | |
2233fc53 | 38 | options.max_open_files = 64; |
cd01a5e1 PW |
39 | if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { |
40 | // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error | |
41 | // on corruption in later versions. | |
42 | options.paranoid_checks = true; | |
43 | } | |
43b7905e PW |
44 | return options; |
45 | } | |
46 | ||
f345c41e | 47 | CDBWrapper::CDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe) |
20e01b1a | 48 | { |
43b7905e PW |
49 | penv = NULL; |
50 | readoptions.verify_checksums = true; | |
51 | iteroptions.verify_checksums = true; | |
52 | iteroptions.fill_cache = false; | |
53 | syncoptions.sync = true; | |
1c83b0a3 | 54 | options = GetOptions(nCacheSize); |
43b7905e | 55 | options.create_if_missing = true; |
e1bfbab8 PW |
56 | if (fMemory) { |
57 | penv = leveldb::NewMemEnv(leveldb::Env::Default()); | |
58 | options.env = penv; | |
59 | } else { | |
7fea4846 | 60 | if (fWipe) { |
7d9d134b | 61 | LogPrintf("Wiping LevelDB in %s\n", path.string()); |
f171fee0 AW |
62 | leveldb::Status result = leveldb::DestroyDB(path.string(), options); |
63 | HandleError(result); | |
7fea4846 | 64 | } |
2b7709dc | 65 | TryCreateDirectory(path); |
7d9d134b | 66 | LogPrintf("Opening LevelDB in %s\n", path.string()); |
e1bfbab8 | 67 | } |
43b7905e | 68 | leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); |
b35e9932 | 69 | HandleError(status); |
881a85a2 | 70 | LogPrintf("Opened LevelDB successfully\n"); |
43b7905e PW |
71 | } |
72 | ||
f345c41e | 73 | CDBWrapper::~CDBWrapper() |
20e01b1a | 74 | { |
43b7905e PW |
75 | delete pdb; |
76 | pdb = NULL; | |
77 | delete options.filter_policy; | |
78 | options.filter_policy = NULL; | |
79 | delete options.block_cache; | |
80 | options.block_cache = NULL; | |
81 | delete penv; | |
82 | options.env = NULL; | |
83 | } | |
84 | ||
f345c41e | 85 | bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) |
20e01b1a | 86 | { |
43b7905e | 87 | leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); |
b35e9932 | 88 | HandleError(status); |
43b7905e PW |
89 | return true; |
90 | } | |
0d81464b | 91 | |
f345c41e | 92 | bool CDBWrapper::IsEmpty() |
0d81464b | 93 | { |
f345c41e | 94 | boost::scoped_ptr<CDBIterator> it(NewIterator()); |
0d81464b JB |
95 | it->SeekToFirst(); |
96 | return !(it->Valid()); | |
97 | } | |
0d9524ba | 98 | |
f345c41e JG |
99 | CDBIterator::~CDBIterator() { delete piter; } |
100 | bool CDBIterator::Valid() { return piter->Valid(); } | |
101 | void CDBIterator::SeekToFirst() { piter->SeekToFirst(); } | |
102 | void CDBIterator::Next() { piter->Next(); } |