From b52a27053850590e0ac8f1431a9aad50b7beffee Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 May 2012 12:21:03 -0400 Subject: [PATCH 1/6] Reorganize(): remove spurious TxnAbort() If Reorganize() fails, then its caller, CBlock::SetBestChain(), will call TxnAbort(). Redundant TxnAbort() calls are harmless. The second will return an error return value, with no other side effects. TxnAbort() return values are generally never checked. The impact is nil. --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 8ff6d6fe..f516ad65 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1438,7 +1438,6 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) if (!block.ConnectBlock(txdb, pindex)) { // Invalid block - txdb.TxnAbort(); return error("Reorganize() : ConnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str()); } From cd9696fc97fc06831c1edede62a063028f2afe75 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 13 May 2012 21:37:39 -0400 Subject: [PATCH 2/6] Encapsulate BDB environment inside new CDBEnv class Cleans up and organizes several scattered functions and variables related to the BDB env. Class CDBInit() existed to provide a guaranteed-via-C++-destructor cleanup of the db environment. A formal CDBEnv class provides all of this inside a single wrapper. --- src/db.cpp | 141 ++++++++++++++++++++++++++--------------------- src/db.h | 30 ++++++++-- src/init.cpp | 6 +- src/walletdb.cpp | 11 ++-- 4 files changed, 110 insertions(+), 78 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 50f08916..988c10ca 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -26,14 +26,11 @@ unsigned int nWalletDBUpdated; // CDB // -CCriticalSection cs_db; -static bool fDbEnvInit = false; -bool fDetachDB = false; -DbEnv dbenv(0); +CDBEnv bitdb; map mapFileUseCount; static map mapDb; -static void EnvShutdown() +void CDBEnv::EnvShutdown() { if (!fDbEnvInit) return; @@ -50,18 +47,67 @@ static void EnvShutdown() DbEnv(0).remove(GetDataDir().string().c_str(), 0); } -class CDBInit +CDBEnv::CDBEnv() : dbenv(0) { -public: - CDBInit() - { - } - ~CDBInit() - { - EnvShutdown(); - } } -instance_of_cdbinit; + +CDBEnv::~CDBEnv() +{ + EnvShutdown(); +} + +void CDBEnv::Close() +{ + EnvShutdown(); +} + +bool CDBEnv::Open(boost::filesystem::path pathEnv_) +{ + if (fDbEnvInit) + return true; + + if (fShutdown) + return false; + + pathEnv = pathEnv_; + filesystem::path pathDataDir = pathEnv; + filesystem::path pathLogDir = pathDataDir / "database"; + filesystem::create_directory(pathLogDir); + filesystem::path pathErrorFile = pathDataDir / "db.log"; + printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); + + int nDbCache = GetArg("-dbcache", 25); + dbenv.set_lg_dir(pathLogDir.string().c_str()); + dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); + dbenv.set_lg_bsize(1048576); + dbenv.set_lg_max(10485760); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug + dbenv.set_flags(DB_AUTO_COMMIT, 1); + dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); + dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); + int ret = dbenv.open(pathDataDir.string().c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_RECOVER, + S_IRUSR | S_IWUSR); + if (ret > 0) + return error("CDB() : error %d opening database environment", ret); + + fDbEnvInit = true; + return true; +} + +void CDBEnv::CheckpointLSN(std::string strFile) +{ + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); +} CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) @@ -77,48 +123,16 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) nFlags |= DB_CREATE; { - LOCK(cs_db); - if (!fDbEnvInit) - { - if (fShutdown) - return; - filesystem::path pathDataDir = GetDataDir(); - filesystem::path pathLogDir = pathDataDir / "database"; - filesystem::create_directory(pathLogDir); - filesystem::path pathErrorFile = pathDataDir / "db.log"; - printf("dbenv.open LogDir=%s ErrorFile=%s\n", pathLogDir.string().c_str(), pathErrorFile.string().c_str()); - - int nDbCache = GetArg("-dbcache", 25); - dbenv.set_lg_dir(pathLogDir.string().c_str()); - dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); - dbenv.set_lg_bsize(1048576); - dbenv.set_lg_max(10485760); - dbenv.set_lk_max_locks(10000); - dbenv.set_lk_max_objects(10000); - dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug - dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1); - dbenv.set_flags(DB_AUTO_COMMIT, 1); - dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); - ret = dbenv.open(pathDataDir.string().c_str(), - DB_CREATE | - DB_INIT_LOCK | - DB_INIT_LOG | - DB_INIT_MPOOL | - DB_INIT_TXN | - DB_THREAD | - DB_RECOVER, - S_IRUSR | S_IWUSR); - if (ret > 0) - throw runtime_error(strprintf("CDB() : error %d opening database environment", ret)); - fDbEnvInit = true; - } + LOCK(bitdb.cs_db); + if (!bitdb.Open(GetDataDir())) + throw runtime_error("env open failed"); strFile = pszFile; ++mapFileUseCount[strFile]; pdb = mapDb[strFile]; if (pdb == NULL) { - pdb = new Db(&dbenv, 0); + pdb = new Db(&bitdb.dbenv, 0); ret = pdb->open(NULL, // Txn pointer pszFile, // Filename @@ -132,7 +146,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) delete pdb; pdb = NULL; { - LOCK(cs_db); + LOCK(bitdb.cs_db); --mapFileUseCount[strFile]; } strFile = ""; @@ -170,10 +184,10 @@ void CDB::Close() if (strFile == "blkindex.dat" && IsInitialBlockDownload()) nMinutes = 5; - dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); + bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0); { - LOCK(cs_db); + LOCK(bitdb.cs_db); --mapFileUseCount[strFile]; } } @@ -181,7 +195,7 @@ void CDB::Close() void CloseDb(const string& strFile) { { - LOCK(cs_db); + LOCK(bitdb.cs_db); if (mapDb[strFile] != NULL) { // Close the database handle @@ -198,13 +212,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) while (!fShutdown) { { - LOCK(cs_db); + LOCK(bitdb.cs_db); if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0) { // Flush log data to the dat file CloseDb(strFile); - dbenv.txn_checkpoint(0, 0, 0); - dbenv.lsn_reset(strFile.c_str(), 0); + bitdb.CheckpointLSN(strFile); mapFileUseCount.erase(strFile); bool fSuccess = true; @@ -212,7 +225,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); - Db* pdbCopy = new Db(&dbenv, 0); + Db* pdbCopy = new Db(&bitdb.dbenv, 0); int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename @@ -270,10 +283,10 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) } if (fSuccess) { - Db dbA(&dbenv, 0); + Db dbA(&bitdb.dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; - Db dbB(&dbenv, 0); + Db dbB(&bitdb.dbenv, 0); if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) fSuccess = false; } @@ -288,12 +301,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) } -void DBFlush(bool fShutdown) +void CDBEnv::Flush(bool fShutdown) { int64 nStart = GetTimeMillis(); // Flush log data to the actual data file // on all files that are not in use - printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); + printf("Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); if (!fDbEnvInit) return; { @@ -327,7 +340,7 @@ void DBFlush(bool fShutdown) if (mapFileUseCount.empty()) { dbenv.log_archive(&listp, DB_ARCH_REMOVE); - EnvShutdown(); + Close(); } } } diff --git a/src/db.h b/src/db.h index 0ff06e40..e2983e07 100644 --- a/src/db.h +++ b/src/db.h @@ -25,14 +25,36 @@ class CWallet; class CWalletTx; extern unsigned int nWalletDBUpdated; -extern bool fDetachDB; -extern DbEnv dbenv; -extern void DBFlush(bool fShutdown); void ThreadFlushWalletDB(void* parg); bool BackupWallet(const CWallet& wallet, const std::string& strDest); +class CDBEnv +{ +private: + bool fDetachDB; + bool fDbEnvInit; + boost::filesystem::path pathEnv; + + void EnvShutdown(); + +public: + mutable CCriticalSection cs_db; + DbEnv dbenv; + + CDBEnv(); + ~CDBEnv(); + bool Open(boost::filesystem::path pathEnv_); + void Close(); + void Flush(bool fShutdown); + void CheckpointLSN(std::string strFile); + void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } +}; + +extern CDBEnv bitdb; + + /** RAII class that provides access to a Berkeley database */ class CDB { @@ -216,7 +238,7 @@ public: if (!pdb) return false; DbTxn* ptxn = NULL; - int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC); + int ret = bitdb.dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC); if (!ptxn || ret != 0) return false; vTxn.push_back(ptxn); diff --git a/src/init.cpp b/src/init.cpp index 829600a4..809c07f3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -54,9 +54,9 @@ void Shutdown(void* parg) { fShutdown = true; nTransactionsUpdated++; - DBFlush(false); + bitdb.Flush(false); StopNode(); - DBFlush(true); + bitdb.Flush(true); boost::filesystem::remove(GetPidFile()); UnregisterWallet(pwalletMain); delete pwalletMain; @@ -294,7 +294,7 @@ bool AppInit2() } fDebug = GetBoolArg("-debug"); - fDetachDB = GetBoolArg("-detachdb", false); + bitdb.SetDetach(GetBoolArg("-detachdb", false)); #if !defined(WIN32) && !defined(QT_GUI) fDaemon = GetBoolArg("-daemon"); diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 7849828a..4bdb7e23 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -13,7 +13,6 @@ using namespace boost; static uint64 nAccountingEntryNumber = 0; -extern CCriticalSection cs_db; extern map mapFileUseCount; extern void CloseDb(const string& strFile); @@ -350,7 +349,7 @@ void ThreadFlushWalletDB(void* parg) if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) { - TRY_LOCK(cs_db,lockDb); + TRY_LOCK(bitdb.cs_db,lockDb); if (lockDb) { // Don't do this if any databases are in use @@ -373,8 +372,7 @@ void ThreadFlushWalletDB(void* parg) // Flush wallet.dat so it's self contained CloseDb(strFile); - dbenv.txn_checkpoint(0, 0, 0); - dbenv.lsn_reset(strFile.c_str(), 0); + bitdb.CheckpointLSN(strFile); mapFileUseCount.erase(mi++); printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); @@ -392,13 +390,12 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) while (!fShutdown) { { - LOCK(cs_db); + LOCK(bitdb.cs_db); if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0) { // Flush log data to the dat file CloseDb(wallet.strWalletFile); - dbenv.txn_checkpoint(0, 0, 0); - dbenv.lsn_reset(wallet.strWalletFile.c_str(), 0); + bitdb.CheckpointLSN(wallet.strWalletFile); mapFileUseCount.erase(wallet.strWalletFile); // Copy wallet.dat From 24b57e3c6a1e5c00e10ee19803dd86d821ffebb2 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 May 2012 12:33:34 -0400 Subject: [PATCH 3/6] Create CDBEnv::TxnBegin(), and use it in CDB::TxnBegin() --- src/db.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/db.h b/src/db.h index e2983e07..aff5e367 100644 --- a/src/db.h +++ b/src/db.h @@ -50,6 +50,15 @@ public: void Flush(bool fShutdown); void CheckpointLSN(std::string strFile); void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } + + DbTxn *TxnBegin(DbTxn *baseTxn, int flags=DB_TXN_WRITE_NOSYNC) + { + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(baseTxn, &ptxn, flags); + if (!ptxn || ret != 0) + return NULL; + return ptxn; + } }; extern CDBEnv bitdb; @@ -237,9 +246,8 @@ public: { if (!pdb) return false; - DbTxn* ptxn = NULL; - int ret = bitdb.dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC); - if (!ptxn || ret != 0) + DbTxn* ptxn = bitdb.TxnBegin(GetTxn()); + if (!ptxn) return false; vTxn.push_back(ptxn); return true; From 8b1202c52c4d8f42c23b02a4cfdb097663e6e7b0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 May 2012 12:39:29 -0400 Subject: [PATCH 4/6] Remove unused nested BDB transaction support --- src/db.cpp | 6 +++--- src/db.h | 44 ++++++++++++++++---------------------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 988c10ca..21b1e0ae 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -170,9 +170,9 @@ void CDB::Close() { if (!pdb) return; - if (!vTxn.empty()) - vTxn.front()->abort(); - vTxn.clear(); + if (activeTxn) + activeTxn->abort(); + activeTxn = NULL; pdb = NULL; // Flush database activity from memory pool to disk log diff --git a/src/db.h b/src/db.h index aff5e367..7af4d5e1 100644 --- a/src/db.h +++ b/src/db.h @@ -51,10 +51,10 @@ public: void CheckpointLSN(std::string strFile); void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } - DbTxn *TxnBegin(DbTxn *baseTxn, int flags=DB_TXN_WRITE_NOSYNC) + DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) { DbTxn* ptxn = NULL; - int ret = dbenv.txn_begin(baseTxn, &ptxn, flags); + int ret = dbenv.txn_begin(NULL, &ptxn, flags); if (!ptxn || ret != 0) return NULL; return ptxn; @@ -70,7 +70,7 @@ class CDB protected: Db* pdb; std::string strFile; - std::vector vTxn; + DbTxn *activeTxn; bool fReadOnly; explicit CDB(const char* pszFile, const char* pszMode="r+"); @@ -97,7 +97,7 @@ protected: // Read Dbt datValue; datValue.set_flags(DB_DBT_MALLOC); - int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); + int ret = pdb->get(activeTxn, &datKey, &datValue, 0); memset(datKey.get_data(), 0, datKey.get_size()); if (datValue.get_data() == NULL) return false; @@ -133,7 +133,7 @@ protected: Dbt datValue(&ssValue[0], ssValue.size()); // Write - int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); // Clear memory in case it was a private key memset(datKey.get_data(), 0, datKey.get_size()); @@ -156,7 +156,7 @@ protected: Dbt datKey(&ssKey[0], ssKey.size()); // Erase - int ret = pdb->del(GetTxn(), &datKey, 0); + int ret = pdb->del(activeTxn, &datKey, 0); // Clear memory memset(datKey.get_data(), 0, datKey.get_size()); @@ -176,7 +176,7 @@ protected: Dbt datKey(&ssKey[0], ssKey.size()); // Exists - int ret = pdb->exists(GetTxn(), &datKey, 0); + int ret = pdb->exists(activeTxn, &datKey, 0); // Clear memory memset(datKey.get_data(), 0, datKey.get_size()); @@ -233,45 +233,33 @@ protected: return 0; } - DbTxn* GetTxn() - { - if (!vTxn.empty()) - return vTxn.back(); - else - return NULL; - } - public: bool TxnBegin() { - if (!pdb) + if (!pdb || activeTxn) return false; - DbTxn* ptxn = bitdb.TxnBegin(GetTxn()); + DbTxn* ptxn = bitdb.TxnBegin(); if (!ptxn) return false; - vTxn.push_back(ptxn); + activeTxn = ptxn; return true; } bool TxnCommit() { - if (!pdb) - return false; - if (vTxn.empty()) + if (!pdb || !activeTxn) return false; - int ret = vTxn.back()->commit(0); - vTxn.pop_back(); + int ret = activeTxn->commit(0); + activeTxn = NULL; return (ret == 0); } bool TxnAbort() { - if (!pdb) - return false; - if (vTxn.empty()) + if (!pdb || !activeTxn) return false; - int ret = vTxn.back()->abort(); - vTxn.pop_back(); + int ret = activeTxn->abort(); + activeTxn = NULL; return (ret == 0); } From 94e34fa0adb818baacdcb6408f0a92e07f3ce7df Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 14 May 2012 22:18:21 -0400 Subject: [PATCH 5/6] CDB::CDB: properly initialize activeTxn to NULL --- src/db.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/db.cpp b/src/db.cpp index 21b1e0ae..08b66141 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -110,7 +110,8 @@ void CDBEnv::CheckpointLSN(std::string strFile) } -CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL) +CDB::CDB(const char *pszFile, const char* pszMode) : + pdb(NULL), activeTxn(NULL) { int ret; if (pszFile == NULL) From ffe8b77a617efd802a9d4ba7e42b163fbd9a250b Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 18 May 2012 02:49:50 -0400 Subject: [PATCH 6/6] Further CDBEnv encapsulation work. --- src/db.cpp | 24 +++++++++++------------- src/db.h | 4 ++++ src/walletdb.cpp | 21 +++++++++------------ 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 08b66141..f0addda9 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -27,8 +27,6 @@ unsigned int nWalletDBUpdated; // CDBEnv bitdb; -map mapFileUseCount; -static map mapDb; void CDBEnv::EnvShutdown() { @@ -129,8 +127,8 @@ CDB::CDB(const char *pszFile, const char* pszMode) : throw runtime_error("env open failed"); strFile = pszFile; - ++mapFileUseCount[strFile]; - pdb = mapDb[strFile]; + ++bitdb.mapFileUseCount[strFile]; + pdb = bitdb.mapDb[strFile]; if (pdb == NULL) { pdb = new Db(&bitdb.dbenv, 0); @@ -148,7 +146,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb = NULL; { LOCK(bitdb.cs_db); - --mapFileUseCount[strFile]; + --bitdb.mapFileUseCount[strFile]; } strFile = ""; throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret)); @@ -162,7 +160,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : fReadOnly = fTmp; } - mapDb[strFile] = pdb; + bitdb.mapDb[strFile] = pdb; } } } @@ -189,14 +187,14 @@ void CDB::Close() { LOCK(bitdb.cs_db); - --mapFileUseCount[strFile]; + --bitdb.mapFileUseCount[strFile]; } } -void CloseDb(const string& strFile) +void CDBEnv::CloseDb(const string& strFile) { { - LOCK(bitdb.cs_db); + LOCK(cs_db); if (mapDb[strFile] != NULL) { // Close the database handle @@ -214,12 +212,12 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) { { LOCK(bitdb.cs_db); - if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0) + if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { // Flush log data to the dat file - CloseDb(strFile); + bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); - mapFileUseCount.erase(strFile); + bitdb.mapFileUseCount.erase(strFile); bool fSuccess = true; printf("Rewriting %s...\n", strFile.c_str()); @@ -276,7 +274,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) if (fSuccess) { db.Close(); - CloseDb(strFile); + bitdb.CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; delete pdbCopy; diff --git a/src/db.h b/src/db.h index 7af4d5e1..abc58c4b 100644 --- a/src/db.h +++ b/src/db.h @@ -42,6 +42,8 @@ private: public: mutable CCriticalSection cs_db; DbEnv dbenv; + std::map mapFileUseCount; + std::map mapDb; CDBEnv(); ~CDBEnv(); @@ -51,6 +53,8 @@ public: void CheckpointLSN(std::string strFile); void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } + void CloseDb(const std::string& strFile); + DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) { DbTxn* ptxn = NULL; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 4bdb7e23..84dedbc8 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -13,9 +13,6 @@ using namespace boost; static uint64 nAccountingEntryNumber = 0; -extern map mapFileUseCount; -extern void CloseDb(const string& strFile); - // // CWalletDB // @@ -354,8 +351,8 @@ void ThreadFlushWalletDB(void* parg) { // Don't do this if any databases are in use int nRefCount = 0; - map::iterator mi = mapFileUseCount.begin(); - while (mi != mapFileUseCount.end()) + map::iterator mi = bitdb.mapFileUseCount.begin(); + while (mi != bitdb.mapFileUseCount.end()) { nRefCount += (*mi).second; mi++; @@ -363,18 +360,18 @@ void ThreadFlushWalletDB(void* parg) if (nRefCount == 0 && !fShutdown) { - map::iterator mi = mapFileUseCount.find(strFile); - if (mi != mapFileUseCount.end()) + map::iterator mi = bitdb.mapFileUseCount.find(strFile); + if (mi != bitdb.mapFileUseCount.end()) { printf("Flushing wallet.dat\n"); nLastFlushed = nWalletDBUpdated; int64 nStart = GetTimeMillis(); // Flush wallet.dat so it's self contained - CloseDb(strFile); + bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); - mapFileUseCount.erase(mi++); + bitdb.mapFileUseCount.erase(mi++); printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); } } @@ -391,12 +388,12 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) { { LOCK(bitdb.cs_db); - if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0) + if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0) { // Flush log data to the dat file - CloseDb(wallet.strWalletFile); + bitdb.CloseDb(wallet.strWalletFile); bitdb.CheckpointLSN(wallet.strWalletFile); - mapFileUseCount.erase(wallet.strWalletFile); + bitdb.mapFileUseCount.erase(wallet.strWalletFile); // Copy wallet.dat filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;