Line data Source code
1 : // Copyright (c) 2012-2014 The Bitcoin developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #include "dbwrapper.h" 6 : 7 : #include <leveldb/cache.h> 8 : #include <leveldb/env.h> 9 : #include <leveldb/filter_policy.h> 10 : #include <memenv.h> 11 : #include <stdint.h> 12 : 13 : 14 3153 : static void SetMaxOpenFiles(leveldb::Options *options) { 15 : // On most platforms the default setting of max_open_files (which is 1000) 16 : // is optimal. On Windows using a large file count is OK because the handles 17 : // do not interfere with select() loops. On 64-bit Unix hosts this value is 18 : // also OK, because up to that amount LevelDB will use an mmap 19 : // implementation that does not use extra file descriptors (the fds are 20 : // closed after being mapped). 21 : // 22 : // Increasing the value beyond the default is dangerous because LevelDB will 23 : // fall back to a non-mmap implementation when the file count is too large. 24 : // On 32-bit Unix host we should decrease the value because the handles use 25 : // up real fds, and we want to avoid fd exhaustion issues. 26 : // 27 : // See PR #12495 for further discussion. 28 : 29 3153 : int default_open_files = options->max_open_files; 30 : #ifndef WIN32 31 3153 : if (sizeof(void*) < 8) { 32 : options->max_open_files = 64; 33 : } 34 : #endif 35 3153 : LogPrint(BCLog::LEVELDB, "LevelDB using max_open_files=%d (default=%d)\n", 36 : options->max_open_files, default_open_files); 37 3153 : } 38 : 39 3153 : static leveldb::Options GetOptions(size_t nCacheSize) 40 : { 41 3153 : leveldb::Options options; 42 3153 : options.block_cache = leveldb::NewLRUCache(nCacheSize / 2); 43 3153 : options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously 44 3153 : options.filter_policy = leveldb::NewBloomFilterPolicy(10); 45 3153 : options.compression = leveldb::kNoCompression; 46 3153 : if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) { 47 : // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error 48 : // on corruption in later versions. 49 3153 : options.paranoid_checks = true; 50 : } 51 3153 : SetMaxOpenFiles(&options); 52 3153 : return options; 53 : } 54 : 55 3153 : CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe, int nVersion) 56 : { 57 3153 : penv = nullptr; 58 3153 : readoptions.verify_checksums = true; 59 3153 : iteroptions.verify_checksums = true; 60 3153 : iteroptions.fill_cache = false; 61 3153 : syncoptions.sync = true; 62 3153 : options = GetOptions(nCacheSize); 63 3153 : options.create_if_missing = true; 64 3153 : this->nVersion = nVersion; 65 3153 : if (fMemory) { 66 1010 : penv = leveldb::NewMemEnv(leveldb::Env::Default()); 67 1010 : options.env = penv; 68 : } else { 69 2143 : if (fWipe) { 70 23 : LogPrintf("Wiping LevelDB in %s\n", path.string()); 71 46 : leveldb::Status result = leveldb::DestroyDB(path.string(), options); 72 23 : dbwrapper_private::HandleError(result); 73 : } 74 2143 : TryCreateDirectories(path); 75 2143 : LogPrintf("Opening LevelDB in %s\n", path.string()); 76 : } 77 3153 : leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb); 78 3153 : dbwrapper_private::HandleError(status); 79 3153 : LogPrintf("Opened LevelDB successfully\n"); 80 3153 : } 81 : 82 6306 : CDBWrapper::~CDBWrapper() 83 : { 84 3153 : delete pdb; 85 3153 : pdb = nullptr; 86 3153 : delete options.filter_policy; 87 3153 : options.filter_policy = nullptr; 88 3153 : delete options.block_cache; 89 3153 : options.block_cache = nullptr; 90 3153 : delete penv; 91 3153 : options.env = nullptr; 92 3153 : } 93 : 94 51560 : bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) 95 : { 96 51560 : leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); 97 51560 : dbwrapper_private::HandleError(status); 98 51560 : return true; 99 : } 100 : 101 0 : bool CDBWrapper::IsEmpty() 102 : { 103 0 : std::unique_ptr<CDBIterator> it(NewIterator()); 104 0 : it->SeekToFirst(); 105 0 : return !(it->Valid()); 106 : } 107 : 108 19608 : CDBIterator::~CDBIterator() { delete piter; } 109 6496401 : bool CDBIterator::Valid() { return piter->Valid(); } 110 0 : void CDBIterator::SeekToFirst() { piter->SeekToFirst(); } 111 6404548 : void CDBIterator::Next() { piter->Next(); } 112 : 113 : 114 : namespace dbwrapper_private { 115 : 116 54736 : void HandleError(const leveldb::Status& status) 117 : { 118 54736 : if (status.ok()) 119 54736 : return; 120 0 : LogPrintf("%s\n", status.ToString()); 121 0 : if (status.IsCorruption()) 122 0 : throw dbwrapper_error("Database corrupted"); 123 0 : if (status.IsIOError()) 124 0 : throw dbwrapper_error("Database I/O error"); 125 0 : if (status.IsNotFound()) 126 0 : throw dbwrapper_error("Database entry missing"); 127 0 : throw dbwrapper_error("Unknown database error"); 128 : } 129 : 130 : };