aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2018-10-24 16:08:54 -0400
committerJoão Barbosa <joao.paulo.barbosa@gmail.com>2019-03-11 21:54:44 +0000
commit7751ea37b65cae2cff766d09b2c95770aa7d71d8 (patch)
tree345f6879b2b588faa922a846082028dda97b7dfe
parentcaf1146b1345d70fbe4cc5f662d8393a79ac6068 (diff)
downloadbitcoin-7751ea37b65cae2cff766d09b2c95770aa7d71d8.tar.xz
Refactor: Move m_db pointers into BerkeleyDatabase
This is a refactoring change that doesn't affect behavior. The motivation behind the change is give BerkeleyEnvironment objects access to BerkeleyDatabase objects so it will be possible to simplify the duplicate wallet check and more reliably avoid opening the same databases twice. Github-Pull: #14552 Rebased-From: c456fbd
-rw-r--r--src/wallet/db.cpp27
-rw-r--r--src/wallet/db.h16
2 files changed, 29 insertions, 14 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index a0f0abd4a6..f7ffd0d6bf 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -107,13 +107,13 @@ void BerkeleyEnvironment::Close()
fDbEnvInit = false;
- for (auto& db : mapDb) {
+ for (auto& db : m_databases) {
auto count = mapFileUseCount.find(db.first);
assert(count == mapFileUseCount.end() || count->second == 0);
- if (db.second) {
- db.second->close(0);
- delete db.second;
- db.second = nullptr;
+ BerkeleyDatabase& database = db.second.get();
+ if (database.m_db) {
+ database.m_db->close(0);
+ database.m_db.reset();
}
}
@@ -480,7 +480,7 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
if (!env->Open(false /* retry */))
throw std::runtime_error("BerkeleyBatch: Failed to open database environment.");
- pdb = env->mapDb[strFilename];
+ pdb = database.m_db.get();
if (pdb == nullptr) {
int ret;
std::unique_ptr<Db> pdb_temp = MakeUnique<Db>(env->dbenv.get(), 0);
@@ -525,7 +525,7 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
}
pdb = pdb_temp.release();
- env->mapDb[strFilename] = pdb;
+ database.m_db.reset(pdb);
if (fCreate && !Exists(std::string("version"))) {
bool fTmp = fReadOnly;
@@ -580,12 +580,13 @@ void BerkeleyEnvironment::CloseDb(const std::string& strFile)
{
{
LOCK(cs_db);
- if (mapDb[strFile] != nullptr) {
+ auto it = m_databases.find(strFile);
+ assert(it != m_databases.end());
+ BerkeleyDatabase& database = it->second.get();
+ if (database.m_db) {
// Close the database handle
- Db* pdb = mapDb[strFile];
- pdb->close(0);
- delete pdb;
- mapDb[strFile] = nullptr;
+ database.m_db->close(0);
+ database.m_db.reset();
}
}
}
@@ -603,7 +604,7 @@ void BerkeleyEnvironment::ReloadDbEnv()
});
std::vector<std::string> filenames;
- for (auto it : mapDb) {
+ for (auto it : m_databases) {
filenames.push_back(it.first);
}
// Close the individual Db's
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 5ced4c59cf..dd549bc463 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -31,6 +31,8 @@ struct WalletDatabaseFileId {
bool operator==(const WalletDatabaseFileId& rhs) const;
};
+class BerkeleyDatabase;
+
class BerkeleyEnvironment
{
private:
@@ -43,7 +45,7 @@ private:
public:
std::unique_ptr<DbEnv> dbenv;
std::map<std::string, int> mapFileUseCount;
- std::map<std::string, Db*> mapDb;
+ std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
std::condition_variable_any m_db_in_use;
@@ -118,6 +120,8 @@ public:
nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0)
{
env = GetWalletEnv(wallet_path, strFile);
+ auto inserted = env->m_databases.emplace(strFile, std::ref(*this));
+ assert(inserted.second);
if (mock) {
env->Close();
env->Reset();
@@ -125,6 +129,13 @@ public:
}
}
+ ~BerkeleyDatabase() {
+ if (env) {
+ size_t erased = env->m_databases.erase(strFile);
+ assert(erased == 1);
+ }
+ }
+
/** Return object for accessing database at specified path. */
static std::unique_ptr<BerkeleyDatabase> Create(const fs::path& path)
{
@@ -164,6 +175,9 @@ public:
unsigned int nLastFlushed;
int64_t nLastWalletUpdate;
+ /** Database pointer. This is initialized lazily and reset during flushes, so it can be null. */
+ std::unique_ptr<Db> m_db;
+
private:
/** BerkeleyDB specific */
BerkeleyEnvironment *env;