wallet: Reduce references to global bitdb environment

This commit is contained in:
Wladimir J. van der Laan 2017-03-08 13:34:47 +00:00
parent 071c95570b
commit be9e1a968d
3 changed files with 48 additions and 33 deletions

View file

@ -364,6 +364,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
int ret; int ret;
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
fFlushOnClose = fFlushOnCloseIn; fFlushOnClose = fFlushOnCloseIn;
env = dbw.env;
if (dbw.IsDummy()) { if (dbw.IsDummy()) {
return; return;
} }
@ -375,17 +376,17 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
nFlags |= DB_CREATE; nFlags |= DB_CREATE;
{ {
LOCK(bitdb.cs_db); LOCK(env->cs_db);
if (!bitdb.Open(GetDataDir())) if (!env->Open(GetDataDir()))
throw std::runtime_error("CDB: Failed to open database environment."); throw std::runtime_error("CDB: Failed to open database environment.");
strFile = strFilename; strFile = strFilename;
++bitdb.mapFileUseCount[strFile]; ++env->mapFileUseCount[strFile];
pdb = bitdb.mapDb[strFile]; pdb = env->mapDb[strFile];
if (pdb == NULL) { if (pdb == NULL) {
pdb = new Db(bitdb.dbenv, 0); pdb = new Db(env->dbenv, 0);
bool fMockDb = bitdb.IsMock(); bool fMockDb = env->IsMock();
if (fMockDb) { if (fMockDb) {
DbMpoolFile* mpf = pdb->get_mpf(); DbMpoolFile* mpf = pdb->get_mpf();
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
@ -403,7 +404,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
if (ret != 0) { if (ret != 0) {
delete pdb; delete pdb;
pdb = NULL; pdb = NULL;
--bitdb.mapFileUseCount[strFile]; --env->mapFileUseCount[strFile];
strFile = ""; strFile = "";
throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename)); throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename));
} }
@ -415,7 +416,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
fReadOnly = fTmp; fReadOnly = fTmp;
} }
bitdb.mapDb[strFile] = pdb; env->mapDb[strFile] = pdb;
} }
} }
} }
@ -430,7 +431,7 @@ void CDB::Flush()
if (fReadOnly) if (fReadOnly)
nMinutes = 1; nMinutes = 1;
bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0); env->dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
} }
void CDB::Close() void CDB::Close()
@ -446,8 +447,8 @@ void CDB::Close()
Flush(); Flush();
{ {
LOCK(bitdb.cs_db); LOCK(env->cs_db);
--bitdb.mapFileUseCount[strFile]; --env->mapFileUseCount[strFile];
} }
} }
@ -479,22 +480,23 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
if (dbw.IsDummy()) { if (dbw.IsDummy()) {
return true; return true;
} }
CDBEnv *env = dbw.env;
const std::string& strFile = dbw.strFile; const std::string& strFile = dbw.strFile;
while (true) { while (true) {
{ {
LOCK(bitdb.cs_db); LOCK(env->cs_db);
if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0) {
// Flush log data to the dat file // Flush log data to the dat file
bitdb.CloseDb(strFile); env->CloseDb(strFile);
bitdb.CheckpointLSN(strFile); env->CheckpointLSN(strFile);
bitdb.mapFileUseCount.erase(strFile); env->mapFileUseCount.erase(strFile);
bool fSuccess = true; bool fSuccess = true;
LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile); LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
std::string strFileRes = strFile + ".rewrite"; std::string strFileRes = strFile + ".rewrite";
{ // surround usage of db with extra {} { // surround usage of db with extra {}
CDB db(dbw, "r"); CDB db(dbw, "r");
Db* pdbCopy = new Db(bitdb.dbenv, 0); Db* pdbCopy = new Db(env->dbenv, 0);
int ret = pdbCopy->open(NULL, // Txn pointer int ret = pdbCopy->open(NULL, // Txn pointer
strFileRes.c_str(), // Filename strFileRes.c_str(), // Filename
@ -537,17 +539,17 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
} }
if (fSuccess) { if (fSuccess) {
db.Close(); db.Close();
bitdb.CloseDb(strFile); env->CloseDb(strFile);
if (pdbCopy->close(0)) if (pdbCopy->close(0))
fSuccess = false; fSuccess = false;
delete pdbCopy; delete pdbCopy;
} }
} }
if (fSuccess) { if (fSuccess) {
Db dbA(bitdb.dbenv, 0); Db dbA(env->dbenv, 0);
if (dbA.remove(strFile.c_str(), NULL, 0)) if (dbA.remove(strFile.c_str(), NULL, 0))
fSuccess = false; fSuccess = false;
Db dbB(bitdb.dbenv, 0); Db dbB(env->dbenv, 0);
if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
fSuccess = false; fSuccess = false;
} }
@ -608,14 +610,15 @@ bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
return true; return true;
} }
bool ret = false; bool ret = false;
CDBEnv *env = dbw.env;
const std::string& strFile = dbw.strFile; const std::string& strFile = dbw.strFile;
TRY_LOCK(bitdb.cs_db,lockDb); TRY_LOCK(bitdb.cs_db,lockDb);
if (lockDb) if (lockDb)
{ {
// Don't do this if any databases are in use // Don't do this if any databases are in use
int nRefCount = 0; int nRefCount = 0;
std::map<std::string, int>::iterator mit = bitdb.mapFileUseCount.begin(); std::map<std::string, int>::iterator mit = env->mapFileUseCount.begin();
while (mit != bitdb.mapFileUseCount.end()) while (mit != env->mapFileUseCount.end())
{ {
nRefCount += (*mit).second; nRefCount += (*mit).second;
mit++; mit++;
@ -624,17 +627,17 @@ bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
if (nRefCount == 0) if (nRefCount == 0)
{ {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
std::map<std::string, int>::iterator mi = bitdb.mapFileUseCount.find(strFile); std::map<std::string, int>::iterator mi = env->mapFileUseCount.find(strFile);
if (mi != bitdb.mapFileUseCount.end()) if (mi != env->mapFileUseCount.end())
{ {
LogPrint(BCLog::DB, "Flushing %s\n", strFile); LogPrint(BCLog::DB, "Flushing %s\n", strFile);
int64_t nStart = GetTimeMillis(); int64_t nStart = GetTimeMillis();
// Flush wallet file so it's self contained // Flush wallet file so it's self contained
bitdb.CloseDb(strFile); env->CloseDb(strFile);
bitdb.CheckpointLSN(strFile); env->CheckpointLSN(strFile);
bitdb.mapFileUseCount.erase(mi++); env->mapFileUseCount.erase(mi++);
LogPrint(BCLog::DB, "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart); LogPrint(BCLog::DB, "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart);
ret = true; ret = true;
} }
@ -657,13 +660,13 @@ bool CWalletDBWrapper::Backup(const std::string& strDest)
while (true) while (true)
{ {
{ {
LOCK(bitdb.cs_db); LOCK(env->cs_db);
if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0)
{ {
// Flush log data to the dat file // Flush log data to the dat file
bitdb.CloseDb(strFile); env->CloseDb(strFile);
bitdb.CheckpointLSN(strFile); env->CheckpointLSN(strFile);
bitdb.mapFileUseCount.erase(strFile); env->mapFileUseCount.erase(strFile);
// Copy wallet file // Copy wallet file
fs::path pathSrc = GetDataDir() / strFile; fs::path pathSrc = GetDataDir() / strFile;
@ -685,3 +688,10 @@ bool CWalletDBWrapper::Backup(const std::string& strDest)
} }
return false; return false;
} }
void CWalletDBWrapper::Flush(bool shutdown)
{
if (!IsDummy()) {
env->Flush(shutdown);
}
}

View file

@ -116,6 +116,10 @@ public:
*/ */
std::string GetName() const { return strFile; } std::string GetName() const { return strFile; }
/** Make sure all changes are flushed to disk.
*/
void Flush(bool shutdown);
/** Return whether this database handle is a dummy for testing. /** Return whether this database handle is a dummy for testing.
* Only to be used at a low level, application should ideally not care * Only to be used at a low level, application should ideally not care
* about this. * about this.
@ -138,6 +142,7 @@ protected:
DbTxn* activeTxn; DbTxn* activeTxn;
bool fReadOnly; bool fReadOnly;
bool fFlushOnClose; bool fFlushOnClose;
CDBEnv *env;
explicit CDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool fFlushOnCloseIn=true); explicit CDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
~CDB() { Close(); } ~CDB() { Close(); }

View file

@ -431,7 +431,7 @@ bool CWallet::HasWalletSpend(const uint256& txid) const
void CWallet::Flush(bool shutdown) void CWallet::Flush(bool shutdown)
{ {
bitdb.Flush(shutdown); dbw->Flush(shutdown);
} }
bool CWallet::Verify() bool CWallet::Verify()