]>
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> |
43b7905e | 15 | |
20e01b1a PW |
16 | void HandleError(const leveldb::Status& status) throw(leveldb_error) |
17 | { | |
421218d3 PW |
18 | if (status.ok()) |
19 | return; | |
7d9d134b | 20 | LogPrintf("%s\n", status.ToString()); |
421218d3 PW |
21 | if (status.IsCorruption()) |
22 | throw leveldb_error("Database corrupted"); | |
23 | if (status.IsIOError()) | |
24 | throw leveldb_error("Database I/O error"); | |
25 | if (status.IsNotFound()) | |
26 | throw leveldb_error("Database entry missing"); | |
27 | throw leveldb_error("Unknown database error"); | |
28 | } | |
29 | ||
20e01b1a PW |
30 | static leveldb::Options GetOptions(size_t nCacheSize) |
31 | { | |
43b7905e | 32 | leveldb::Options options; |
1c83b0a3 PW |
33 | options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); |
34 | options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously | |
43b7905e PW |
35 | options.filter_policy = leveldb::NewBloomFilterPolicy(10); |
36 | options.compression = leveldb::kNoCompression; | |
2233fc53 | 37 | options.max_open_files = 64; |
cd01a5e1 PW |
38 | if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { |
39 | // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error | |
40 | // on corruption in later versions. | |
41 | options.paranoid_checks = true; | |
42 | } | |
43b7905e PW |
43 | return options; |
44 | } | |
45 | ||
20e01b1a PW |
46 | CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCacheSize, bool fMemory, bool fWipe) |
47 | { | |
43b7905e PW |
48 | penv = NULL; |
49 | readoptions.verify_checksums = true; | |
50 | iteroptions.verify_checksums = true; | |
51 | iteroptions.fill_cache = false; | |
52 | syncoptions.sync = true; | |
1c83b0a3 | 53 | options = GetOptions(nCacheSize); |
43b7905e | 54 | options.create_if_missing = true; |
e1bfbab8 PW |
55 | if (fMemory) { |
56 | penv = leveldb::NewMemEnv(leveldb::Env::Default()); | |
57 | options.env = penv; | |
58 | } else { | |
7fea4846 | 59 | if (fWipe) { |
7d9d134b | 60 | LogPrintf("Wiping LevelDB in %s\n", path.string()); |
7fea4846 PW |
61 | leveldb::DestroyDB(path.string(), options); |
62 | } | |
2b7709dc | 63 | TryCreateDirectory(path); |
7d9d134b | 64 | LogPrintf("Opening LevelDB in %s\n", path.string()); |
e1bfbab8 | 65 | } |
43b7905e | 66 | leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); |
b35e9932 | 67 | HandleError(status); |
881a85a2 | 68 | LogPrintf("Opened LevelDB successfully\n"); |
43b7905e PW |
69 | } |
70 | ||
20e01b1a PW |
71 | CLevelDBWrapper::~CLevelDBWrapper() |
72 | { | |
43b7905e PW |
73 | delete pdb; |
74 | pdb = NULL; | |
75 | delete options.filter_policy; | |
76 | options.filter_policy = NULL; | |
77 | delete options.block_cache; | |
78 | options.block_cache = NULL; | |
79 | delete penv; | |
80 | options.env = NULL; | |
81 | } | |
82 | ||
20e01b1a PW |
83 | bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) throw(leveldb_error) |
84 | { | |
43b7905e | 85 | leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); |
b35e9932 | 86 | HandleError(status); |
43b7905e PW |
87 | return true; |
88 | } |