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