Merge pull request #1981 from sipa/caches

Cache size optimizations
This commit is contained in:
Pieter Wuille 2012-11-08 14:17:37 -08:00
commit 16d9d61f99
7 changed files with 27 additions and 14 deletions

View File

@ -236,7 +236,6 @@ std::string HelpMessage()
" -gen=0 " + _("Don't generate coins") + "\n" + " -gen=0 " + _("Don't generate coins") + "\n" +
" -datadir=<dir> " + _("Specify data directory") + "\n" + " -datadir=<dir> " + _("Specify data directory") + "\n" +
" -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" +
" -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
" -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" + " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" +
" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" + " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
" -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + " -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
@ -651,11 +650,23 @@ bool AppInit2()
return InitError(msg); return InitError(msg);
} }
// cache size calculations
size_t nTotalCache = GetArg("-dbcache", 25) << 20;
if (nTotalCache < (1 << 22))
nTotalCache = (1 << 22); // total cache cannot be less than 4 MiB
size_t nBlockTreeDBCache = nTotalCache / 8;
if (nBlockTreeDBCache > (1 << 21))
nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
nTotalCache -= nBlockTreeDBCache;
size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache
nTotalCache -= nCoinDBCache;
nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
uiInterface.InitMessage(_("Loading block index...")); uiInterface.InitMessage(_("Loading block index..."));
printf("Loading block index...\n"); printf("Loading block index...\n");
nStart = GetTimeMillis(); nStart = GetTimeMillis();
pblocktree = new CBlockTreeDB(); pblocktree = new CBlockTreeDB(nBlockTreeDBCache);
pcoinsdbview = new CCoinsViewDB(); pcoinsdbview = new CCoinsViewDB(nCoinDBCache);
pcoinsTip = new CCoinsViewCache(*pcoinsdbview); pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
if (!LoadBlockIndex()) if (!LoadBlockIndex())

View File

@ -12,22 +12,22 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
static leveldb::Options GetOptions() { static leveldb::Options GetOptions(size_t nCacheSize) {
leveldb::Options options; leveldb::Options options;
int nCacheSizeMB = GetArg("-dbcache", 25); options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
options.block_cache = leveldb::NewLRUCache(nCacheSizeMB * 1048576); options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
options.filter_policy = leveldb::NewBloomFilterPolicy(10); options.filter_policy = leveldb::NewBloomFilterPolicy(10);
options.compression = leveldb::kNoCompression; options.compression = leveldb::kNoCompression;
return options; return options;
} }
CLevelDB::CLevelDB(const boost::filesystem::path &path, bool fMemory) { CLevelDB::CLevelDB(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory) {
penv = NULL; penv = NULL;
readoptions.verify_checksums = true; readoptions.verify_checksums = true;
iteroptions.verify_checksums = true; iteroptions.verify_checksums = true;
iteroptions.fill_cache = false; iteroptions.fill_cache = false;
syncoptions.sync = true; syncoptions.sync = true;
options = GetOptions(); options = GetOptions(nCacheSize);
options.create_if_missing = true; options.create_if_missing = true;
if (fMemory) { if (fMemory) {
penv = leveldb::NewMemEnv(leveldb::Env::Default()); penv = leveldb::NewMemEnv(leveldb::Env::Default());

View File

@ -69,7 +69,7 @@ private:
leveldb::DB *pdb; leveldb::DB *pdb;
public: public:
CLevelDB(const boost::filesystem::path &path, bool fMemory = false); CLevelDB(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory = false);
~CLevelDB(); ~CLevelDB();
template<typename K, typename V> bool Read(const K& key, V& value) { template<typename K, typename V> bool Read(const K& key, V& value) {

View File

@ -41,6 +41,7 @@ CBlockIndex* pindexBest = NULL;
set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed
int64 nTimeBestReceived = 0; int64 nTimeBestReceived = 0;
bool fImporting = false; bool fImporting = false;
unsigned int nCoinCacheSize = 5000;
CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have
@ -1735,7 +1736,7 @@ bool SetBestChain(CBlockIndex* pindexNew)
// Make sure it's successfully written to disk before changing memory structure // Make sure it's successfully written to disk before changing memory structure
bool fIsInitialDownload = IsInitialBlockDownload(); bool fIsInitialDownload = IsInitialBlockDownload();
if (!fIsInitialDownload || view.GetCacheSize()>5000) { if (!fIsInitialDownload || view.GetCacheSize() > nCoinCacheSize) {
FlushBlockFile(); FlushBlockFile();
pblocktree->Sync(); pblocktree->Sync();
if (!view.Flush()) if (!view.Flush())

View File

@ -88,6 +88,7 @@ extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered; extern std::set<CWallet*> setpwalletRegistered;
extern unsigned char pchMessageStart[4]; extern unsigned char pchMessageStart[4];
extern bool fImporting; extern bool fImporting;
extern unsigned int nCoinCacheSize;
// Settings // Settings
extern int64 nTransactionFee; extern int64 nTransactionFee;

View File

@ -19,7 +19,7 @@ void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
batch.Write('B', hash); batch.Write('B', hash);
} }
CCoinsViewDB::CCoinsViewDB(bool fMemory) : db(GetDataDir() / "coins", fMemory) { CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory) : db(GetDataDir() / "coins", nCacheSize, fMemory) {
} }
bool CCoinsViewDB::GetCoins(uint256 txid, CCoins &coins) { bool CCoinsViewDB::GetCoins(uint256 txid, CCoins &coins) {
@ -64,7 +64,7 @@ bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockI
return db.WriteBatch(batch); return db.WriteBatch(batch);
} }
CBlockTreeDB::CBlockTreeDB(bool fMemory) : CLevelDB(GetDataDir() / "blktree", fMemory) { CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory) : CLevelDB(GetDataDir() / "blktree", nCacheSize, fMemory) {
} }
bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)

View File

@ -14,7 +14,7 @@ class CCoinsViewDB : public CCoinsView
protected: protected:
CLevelDB db; CLevelDB db;
public: public:
CCoinsViewDB(bool fMemory = false); CCoinsViewDB(size_t nCacheSize, bool fMemory = false);
bool GetCoins(uint256 txid, CCoins &coins); bool GetCoins(uint256 txid, CCoins &coins);
bool SetCoins(uint256 txid, const CCoins &coins); bool SetCoins(uint256 txid, const CCoins &coins);
@ -29,7 +29,7 @@ public:
class CBlockTreeDB : public CLevelDB class CBlockTreeDB : public CLevelDB
{ {
public: public:
CBlockTreeDB(bool fMemory = false); CBlockTreeDB(size_t nCacheSize, bool fMemory = false);
private: private:
CBlockTreeDB(const CBlockTreeDB&); CBlockTreeDB(const CBlockTreeDB&);
void operator=(const CBlockTreeDB&); void operator=(const CBlockTreeDB&);