Skip to content

Commit 4fe4b3b

Browse files
committed
walletdb: track database file use as m_refcount within BerkeleyDatabase
Instead of having BerkeleyEnvironment track the file use count, make BerkeleyDatabase do it itself.
1 parent 65fb880 commit 4fe4b3b

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

src/wallet/bdb.cpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,8 @@ void BerkeleyEnvironment::Close()
9797
fDbEnvInit = false;
9898

9999
for (auto& db : m_databases) {
100-
auto count = mapFileUseCount.find(db.first);
101-
assert(count == mapFileUseCount.end() || count->second == 0);
102100
BerkeleyDatabase& database = db.second.get();
101+
assert(database.m_refcount <= 0);
103102
if (database.m_db) {
104103
database.m_db->close(0);
105104
database.m_db.reset();
@@ -285,8 +284,7 @@ bool BerkeleyDatabase::Verify(bilingual_str& errorStr)
285284

286285
if (fs::exists(file_path))
287286
{
288-
LOCK(cs_db);
289-
assert(env->mapFileUseCount.count(strFile) == 0);
287+
assert(m_refcount == 0);
290288

291289
Db db(env->dbenv.get(), 0);
292290
int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
@@ -459,8 +457,8 @@ void BerkeleyEnvironment::ReloadDbEnv()
459457
AssertLockNotHeld(cs_db);
460458
std::unique_lock<RecursiveMutex> lock(cs_db);
461459
m_db_in_use.wait(lock, [this](){
462-
for (auto& count : mapFileUseCount) {
463-
if (count.second > 0) return false;
460+
for (auto& db : m_databases) {
461+
if (db.second.get().m_refcount > 0) return false;
464462
}
465463
return true;
466464
});
@@ -488,11 +486,11 @@ bool BerkeleyDatabase::Rewrite(const char* pszSkip)
488486
while (true) {
489487
{
490488
LOCK(cs_db);
491-
if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0) {
489+
if (m_refcount <= 0) {
492490
// Flush log data to the dat file
493491
env->CloseDb(strFile);
494492
env->CheckpointLSN(strFile);
495-
env->mapFileUseCount.erase(strFile);
493+
m_refcount = -1;
496494

497495
bool fSuccess = true;
498496
LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile);
@@ -576,10 +574,11 @@ void BerkeleyEnvironment::Flush(bool fShutdown)
576574
return;
577575
{
578576
LOCK(cs_db);
579-
std::map<std::string, int>::iterator mi = mapFileUseCount.begin();
580-
while (mi != mapFileUseCount.end()) {
581-
std::string strFile = (*mi).first;
582-
int nRefCount = (*mi).second;
577+
bool no_dbs_accessed = true;
578+
for (auto& db_it : m_databases) {
579+
std::string strFile = db_it.first;
580+
int nRefCount = db_it.second.get().m_refcount;
581+
if (nRefCount < 0) continue;
583582
LogPrint(BCLog::WALLETDB, "BerkeleyEnvironment::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount);
584583
if (nRefCount == 0) {
585584
// Move log data to the dat file
@@ -590,14 +589,15 @@ void BerkeleyEnvironment::Flush(bool fShutdown)
590589
if (!fMockDb)
591590
dbenv->lsn_reset(strFile.c_str(), 0);
592591
LogPrint(BCLog::WALLETDB, "BerkeleyEnvironment::Flush: %s closed\n", strFile);
593-
mapFileUseCount.erase(mi++);
594-
} else
595-
mi++;
592+
nRefCount = -1;
593+
} else {
594+
no_dbs_accessed = false;
595+
}
596596
}
597597
LogPrint(BCLog::WALLETDB, "BerkeleyEnvironment::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
598598
if (fShutdown) {
599599
char** listp;
600-
if (mapFileUseCount.empty()) {
600+
if (no_dbs_accessed) {
601601
dbenv->log_archive(&listp, DB_ARCH_REMOVE);
602602
Close();
603603
if (!fMockDb) {
@@ -618,21 +618,20 @@ bool BerkeleyDatabase::PeriodicFlush()
618618
if (!lockDb) return false;
619619

620620
// Don't flush if any databases are in use
621-
for (const auto& use_count : env->mapFileUseCount) {
622-
if (use_count.second > 0) return false;
621+
for (auto& it : env->m_databases) {
622+
if (it.second.get().m_refcount > 0) return false;
623623
}
624624

625625
// Don't flush if there haven't been any batch writes for this database.
626-
auto it = env->mapFileUseCount.find(strFile);
627-
if (it == env->mapFileUseCount.end()) return false;
626+
if (m_refcount < 0) return false;
628627

629628
LogPrint(BCLog::WALLETDB, "Flushing %s\n", strFile);
630629
int64_t nStart = GetTimeMillis();
631630

632631
// Flush wallet file so it's self contained
633632
env->CloseDb(strFile);
634633
env->CheckpointLSN(strFile);
635-
env->mapFileUseCount.erase(it);
634+
m_refcount = -1;
636635

637636
LogPrint(BCLog::WALLETDB, "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart);
638637

@@ -648,12 +647,11 @@ bool BerkeleyDatabase::Backup(const std::string& strDest) const
648647
{
649648
{
650649
LOCK(cs_db);
651-
if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0)
650+
if (m_refcount <= 0)
652651
{
653652
// Flush log data to the dat file
654653
env->CloseDb(strFile);
655654
env->CheckpointLSN(strFile);
656-
env->mapFileUseCount.erase(strFile);
657655

658656
// Copy wallet file
659657
fs::path pathSrc = env->Directory() / strFile;
@@ -835,15 +833,17 @@ bool BerkeleyBatch::HasKey(CDataStream&& key)
835833
void BerkeleyDatabase::AddRef()
836834
{
837835
LOCK(cs_db);
838-
++env->mapFileUseCount[strFile];
836+
if (m_refcount < 0) {
837+
m_refcount = 1;
838+
} else {
839+
m_refcount++;
840+
}
839841
}
840842

841843
void BerkeleyDatabase::RemoveRef()
842844
{
843-
{
844-
LOCK(cs_db);
845-
--env->mapFileUseCount[strFile];
846-
}
845+
LOCK(cs_db);
846+
m_refcount--;
847847
env->m_db_in_use.notify_all();
848848
}
849849

src/wallet/bdb.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ class BerkeleyEnvironment
5252

5353
public:
5454
std::unique_ptr<DbEnv> dbenv;
55-
std::map<std::string, int> mapFileUseCount;
5655
std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
5756
std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
5857
std::condition_variable_any m_db_in_use;

0 commit comments

Comments
 (0)