PRCYCoin  2.0.0.7rc1
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 "util.h"
8 
9 #include <boost/scoped_ptr.hpp>
10 
11 #include <leveldb/cache.h>
12 #include <leveldb/env.h>
13 #include <leveldb/filter_policy.h>
14 #include <memenv.h>
15 #include <stdint.h>
16 
17 static void SetMaxOpenFiles(leveldb::Options *options) {
18  // On most platforms the default setting of max_open_files (which is 1000)
19  // is optimal. On Windows using a large file count is OK because the handles
20  // do not interfere with select() loops. On 64-bit Unix hosts this value is
21  // also OK, because up to that amount LevelDB will use an mmap
22  // implementation that does not use extra file descriptors (the fds are
23  // closed after being mmaped).
24  //
25  // Increasing the value beyond the default is dangerous because LevelDB will
26  // fall back to a non-mmap implementation when the file count is too large.
27  // On 32-bit Unix host we should decrease the value because the handles use
28  // up real fds, and we want to avoid fd exhaustion issues.
29  //
30  // See PR #12495 for further discussion.
31 
32  int default_open_files = options->max_open_files;
33 #ifndef WIN32
34  if (sizeof(void*) < 8) {
35  options->max_open_files = 64;
36  }
37 #endif
38  LogPrintf("LevelDB using max_open_files=%d (default=%d)\n",
39  options->max_open_files, default_open_files);
40 }
41 
42 static leveldb::Options GetOptions(size_t nCacheSize)
43 {
44  leveldb::Options options;
45  options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
46  options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
47  options.filter_policy = leveldb::NewBloomFilterPolicy(10);
48  options.compression = leveldb::kNoCompression;
49  if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) {
50  // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error
51  // on corruption in later versions.
52  options.paranoid_checks = true;
53  }
54  SetMaxOpenFiles(&options);
55  return options;
56 }
57 
58 CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe)
59 {
60  penv = NULL;
61  readoptions.verify_checksums = true;
62  iteroptions.verify_checksums = true;
63  iteroptions.fill_cache = false;
64  syncoptions.sync = true;
65  options = GetOptions(nCacheSize);
66  options.create_if_missing = true;
67  if (fMemory) {
68  penv = leveldb::NewMemEnv(leveldb::Env::Default());
69  options.env = penv;
70  } else {
71  if (fWipe) {
72  LogPrintf("Wiping LevelDB in %s\n", path.string());
73  leveldb::Status result = leveldb::DestroyDB(path.string(), options);
75  }
76  TryCreateDirectory(path);
77  LogPrintf("Opening LevelDB in %s\n", path.string());
78  }
79  leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
81  LogPrintf("Opened LevelDB successfully\n");
82 }
83 
85 {
86  delete pdb;
87  pdb = NULL;
88  delete options.filter_policy;
89  options.filter_policy = NULL;
90  delete options.block_cache;
91  options.block_cache = NULL;
92  delete penv;
93  options.env = NULL;
94 }
95 
96 bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
97 {
98  leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
100  return true;
101 }
102 
104 {
105  boost::scoped_ptr<CDBIterator> it(NewIterator());
106  it->SeekToFirst();
107  return !(it->Valid());
108 }
109 
111 bool CDBIterator::Valid() { return piter->Valid(); }
112 void CDBIterator::SeekToFirst() { piter->SeekToFirst(); }
113 void CDBIterator::Next() { piter->Next(); }
114 
115 namespace dbwrapper_private {
116 
117 void HandleError(const leveldb::Status& status)
118 {
119  if (status.ok())
120  return;
121  const std::string errmsg = "Fatal LevelDB error: " + status.ToString();
122  LogPrintf("%s\n", errmsg);
123  LogPrintf("You can use -debug=leveldb to get more complete diagnostic messages\n");
124  throw dbwrapper_error(errmsg);
125 }
126 
127 };
dbwrapper.h
CDBBatch
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:39
CDBWrapper::readoptions
leveldb::ReadOptions readoptions
options used when reading from the database
Definition: dbwrapper.h:144
CDBWrapper::syncoptions
leveldb::WriteOptions syncoptions
options used when sync writing to the database
Definition: dbwrapper.h:153
CDBIterator::Next
void Next()
Definition: dbwrapper.cpp:113
CDBIterator::Valid
bool Valid()
Definition: dbwrapper.cpp:111
CDBWrapper::NewIterator
CDBIterator * NewIterator()
Definition: dbwrapper.h:243
CDBWrapper::iteroptions
leveldb::ReadOptions iteroptions
options used when iterating over values of the database
Definition: dbwrapper.h:147
CDBWrapper::penv
leveldb::Env * penv
custom environment this database is using (may be NULL in case of default environment)
Definition: dbwrapper.h:138
CDBIterator::~CDBIterator
~CDBIterator()
Definition: dbwrapper.cpp:110
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
CDBBatch::batch
leveldb::WriteBatch batch
Definition: dbwrapper.h:44
CDBWrapper::pdb
leveldb::DB * pdb
the database itself
Definition: dbwrapper.h:156
dbwrapper_private
These should be considered an implementation detail of the specific database.
Definition: dbwrapper.cpp:115
CDBIterator::piter
leveldb::Iterator * piter
Definition: dbwrapper.h:79
CDBWrapper::writeoptions
leveldb::WriteOptions writeoptions
options used when writing to the database
Definition: dbwrapper.h:150
dbwrapper_private::HandleError
void HandleError(const leveldb::Status &status)
Handle database error by throwing dbwrapper_error exception.
Definition: dbwrapper.cpp:117
dbwrapper_error
Definition: dbwrapper.h:19
CDBWrapper::options
leveldb::Options options
database options used
Definition: dbwrapper.h:141
CDBWrapper::~CDBWrapper
~CDBWrapper()
Definition: dbwrapper.cpp:84
CDBWrapper::CDBWrapper
CDBWrapper(const fs::path &path, size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: dbwrapper.cpp:58
CDBIterator::SeekToFirst
void SeekToFirst()
Definition: dbwrapper.cpp:112
CDBWrapper::IsEmpty
bool IsEmpty()
Return true if the database managed by this class contains no entries.
Definition: dbwrapper.cpp:103
util.h
CDBWrapper::WriteBatch
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:96
TryCreateDirectory
bool TryCreateDirectory(const fs::path &p)
Ignores exceptions thrown by Boost's create_directory if the requested directory exists.
Definition: util.cpp:464