PIVX Core  5.6.99
P2P Digital Currency
dbwrapper.cpp
Go to the documentation of this file.
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 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  int default_open_files = options->max_open_files;
30 #ifndef WIN32
31  if (sizeof(void*) < 8) {
32  options->max_open_files = 64;
33  }
34 #endif
35  LogPrint(BCLog::LEVELDB, "LevelDB using max_open_files=%d (default=%d)\n",
36  options->max_open_files, default_open_files);
37 }
38 
39 static leveldb::Options GetOptions(size_t nCacheSize)
40 {
41  leveldb::Options options;
42  options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
43  options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
44  options.filter_policy = leveldb::NewBloomFilterPolicy(10);
45  options.compression = leveldb::kNoCompression;
46  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  options.paranoid_checks = true;
50  }
51  SetMaxOpenFiles(&options);
52  return options;
53 }
54 
55 CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe, int nVersion)
56 {
57  penv = nullptr;
58  readoptions.verify_checksums = true;
59  iteroptions.verify_checksums = true;
60  iteroptions.fill_cache = false;
61  syncoptions.sync = true;
62  options = GetOptions(nCacheSize);
63  options.create_if_missing = true;
64  this->nVersion = nVersion;
65  if (fMemory) {
66  penv = leveldb::NewMemEnv(leveldb::Env::Default());
67  options.env = penv;
68  } else {
69  if (fWipe) {
70  LogPrintf("Wiping LevelDB in %s\n", path.string());
71  leveldb::Status result = leveldb::DestroyDB(path.string(), options);
73  }
75  LogPrintf("Opening LevelDB in %s\n", path.string());
76  }
77  leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
79  LogPrintf("Opened LevelDB successfully\n");
80 }
81 
83 {
84  delete pdb;
85  pdb = nullptr;
86  delete options.filter_policy;
87  options.filter_policy = nullptr;
88  delete options.block_cache;
89  options.block_cache = nullptr;
90  delete penv;
91  options.env = nullptr;
92 }
93 
94 bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
95 {
96  leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
98  return true;
99 }
100 
102 {
103  std::unique_ptr<CDBIterator> it(NewIterator());
104  it->SeekToFirst();
105  return !(it->Valid());
106 }
107 
109 bool CDBIterator::Valid() { return piter->Valid(); }
110 void CDBIterator::SeekToFirst() { piter->SeekToFirst(); }
111 void CDBIterator::Next() { piter->Next(); }
112 
113 
114 namespace dbwrapper_private {
115 
116 void HandleError(const leveldb::Status& status)
117 {
118  if (status.ok())
119  return;
120  LogPrintf("%s\n", status.ToString());
121  if (status.IsCorruption())
122  throw dbwrapper_error("Database corrupted");
123  if (status.IsIOError())
124  throw dbwrapper_error("Database I/O error");
125  if (status.IsNotFound())
126  throw dbwrapper_error("Database entry missing");
127  throw dbwrapper_error("Unknown database error");
128 }
129 
130 };
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:46
leveldb::WriteBatch batch
Definition: dbwrapper.h:50
bool Valid()
Definition: dbwrapper.cpp:109
leveldb::Iterator * piter
Definition: dbwrapper.h:128
void SeekToFirst()
Definition: dbwrapper.cpp:110
void Next()
Definition: dbwrapper.cpp:111
CDBIterator * NewIterator()
Definition: dbwrapper.h:338
leveldb::Env * penv
custom environment this database is using (may be nullptr in case of default environment)
Definition: dbwrapper.h:199
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:94
CDBWrapper(const fs::path &path, size_t nCacheSize, bool fMemory=false, bool fWipe=false, int nVersion=CLIENT_VERSION)
Definition: dbwrapper.cpp:55
leveldb::Options options
database options used
Definition: dbwrapper.h:202
leveldb::WriteOptions writeoptions
options used when writing to the database
Definition: dbwrapper.h:211
leveldb::WriteOptions syncoptions
options used when sync writing to the database
Definition: dbwrapper.h:214
int nVersion
the version used to serialize data
Definition: dbwrapper.h:220
leveldb::DB * pdb
the database itself
Definition: dbwrapper.h:217
leveldb::ReadOptions iteroptions
options used when iterating over values of the database
Definition: dbwrapper.h:208
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:101
leveldb::ReadOptions readoptions
options used when reading from the database
Definition: dbwrapper.h:205
#define LogPrint(category,...)
Definition: logging.h:163
@ LEVELDB
Definition: logging.h:57
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:114
void HandleError(const leveldb::Status &status)
Handle database error by throwing dbwrapper_error exception.
Definition: dbwrapper.cpp:116
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
Definition: system.cpp:891