walletdb: Move Db->open to BerkeleyDatabase::Open

Instead of opening the Db handle in BerkeleyBatch, make BerkeleyDatabase
do that.
This commit is contained in:
Andrew Chow
2020-05-10 22:41:34 -04:00
parent 4fe4b3bf1b
commit d86efab370
2 changed files with 32 additions and 29 deletions

View File

@@ -317,13 +317,27 @@ BerkeleyDatabase::~BerkeleyDatabase()
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr), m_database(database) BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr), m_database(database)
{ {
database.AddRef();
database.Open(pszMode);
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
fFlushOnClose = fFlushOnCloseIn; fFlushOnClose = fFlushOnCloseIn;
env = database.env.get(); env = database.env.get();
if (database.IsDummy()) { pdb = database.m_db.get();
strFile = database.strFile;
bool fCreate = strchr(pszMode, 'c') != nullptr;
if (fCreate && !Exists(std::string("version"))) {
bool fTmp = fReadOnly;
fReadOnly = false;
Write(std::string("version"), CLIENT_VERSION);
fReadOnly = fTmp;
}
}
void BerkeleyDatabase::Open(const char* pszMode)
{
if (IsDummy()){
return; return;
} }
const std::string &strFilename = database.strFile;
bool fCreate = strchr(pszMode, 'c') != nullptr; bool fCreate = strchr(pszMode, 'c') != nullptr;
unsigned int nFlags = DB_THREAD; unsigned int nFlags = DB_THREAD;
@@ -334,10 +348,9 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
LOCK(cs_db); LOCK(cs_db);
bilingual_str open_err; bilingual_str open_err;
if (!env->Open(open_err)) if (!env->Open(open_err))
throw std::runtime_error("BerkeleyBatch: Failed to open database environment."); throw std::runtime_error("BerkeleyDatabase: Failed to open database environment.");
pdb = database.m_db.get(); if (m_db == nullptr) {
if (pdb == nullptr) {
int ret; int ret;
std::unique_ptr<Db> pdb_temp = MakeUnique<Db>(env->dbenv.get(), 0); std::unique_ptr<Db> pdb_temp = MakeUnique<Db>(env->dbenv.get(), 0);
@@ -346,19 +359,19 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
DbMpoolFile* mpf = pdb_temp->get_mpf(); DbMpoolFile* mpf = pdb_temp->get_mpf();
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
if (ret != 0) { if (ret != 0) {
throw std::runtime_error(strprintf("BerkeleyBatch: Failed to configure for no temp file backing for database %s", strFilename)); throw std::runtime_error(strprintf("BerkeleyDatabase: Failed to configure for no temp file backing for database %s", strFile));
} }
} }
ret = pdb_temp->open(nullptr, // Txn pointer ret = pdb_temp->open(nullptr, // Txn pointer
fMockDb ? nullptr : strFilename.c_str(), // Filename fMockDb ? nullptr : strFile.c_str(), // Filename
fMockDb ? strFilename.c_str() : "main", // Logical db name fMockDb ? strFile.c_str() : "main", // Logical db name
DB_BTREE, // Database type DB_BTREE, // Database type
nFlags, // Flags nFlags, // Flags
0); 0);
if (ret != 0) { if (ret != 0) {
throw std::runtime_error(strprintf("BerkeleyBatch: Error %d, can't open database %s", ret, strFilename)); throw std::runtime_error(strprintf("BerkeleyDatabase: Error %d, can't open database %s", ret, strFile));
} }
// Call CheckUniqueFileid on the containing BDB environment to // Call CheckUniqueFileid on the containing BDB environment to
@@ -377,29 +390,15 @@ BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bo
// versions of BDB have an set_lk_exclusive method for this // versions of BDB have an set_lk_exclusive method for this
// purpose, but the older version we use does not.) // purpose, but the older version we use does not.)
for (const auto& env : g_dbenvs) { for (const auto& env : g_dbenvs) {
CheckUniqueFileid(*env.second.lock().get(), strFilename, *pdb_temp, this->env->m_fileids[strFilename]); CheckUniqueFileid(*env.second.lock().get(), strFile, *pdb_temp, this->env->m_fileids[strFile]);
} }
pdb = pdb_temp.release(); m_db.reset(pdb_temp.release());
database.m_db.reset(pdb);
if (fCreate && !Exists(std::string("version"))) {
bool fTmp = fReadOnly;
fReadOnly = false;
Write(std::string("version"), CLIENT_VERSION);
fReadOnly = fTmp;
}
} }
database.AddRef();
strFile = strFilename;
} }
} }
void BerkeleyDatabase::Open(const char* mode)
{
throw std::logic_error("BerkeleyDatabase does not implement Open. This function should not be called.");
}
void BerkeleyBatch::Flush() void BerkeleyBatch::Flush()
{ {
if (activeTxn) if (activeTxn)
@@ -420,6 +419,12 @@ void BerkeleyDatabase::IncrementUpdateCounter()
++nUpdateCounter; ++nUpdateCounter;
} }
BerkeleyBatch::~BerkeleyBatch()
{
Close();
m_database.RemoveRef();
}
void BerkeleyBatch::Close() void BerkeleyBatch::Close()
{ {
if (!pdb) if (!pdb)
@@ -432,8 +437,6 @@ void BerkeleyBatch::Close()
if (fFlushOnClose) if (fFlushOnClose)
Flush(); Flush();
m_database.RemoveRef();
} }
void BerkeleyEnvironment::CloseDb(const std::string& strFile) void BerkeleyEnvironment::CloseDb(const std::string& strFile)
@@ -844,7 +847,7 @@ void BerkeleyDatabase::RemoveRef()
{ {
LOCK(cs_db); LOCK(cs_db);
m_refcount--; m_refcount--;
env->m_db_in_use.notify_all(); if (env) env->m_db_in_use.notify_all();
} }
std::unique_ptr<DatabaseBatch> BerkeleyDatabase::MakeBatch(const char* mode, bool flush_on_close) std::unique_ptr<DatabaseBatch> BerkeleyDatabase::MakeBatch(const char* mode, bool flush_on_close)

View File

@@ -217,7 +217,7 @@ protected:
public: public:
explicit BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode = "r+", bool fFlushOnCloseIn=true); explicit BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
~BerkeleyBatch() override { Close(); } ~BerkeleyBatch() override;
BerkeleyBatch(const BerkeleyBatch&) = delete; BerkeleyBatch(const BerkeleyBatch&) = delete;
BerkeleyBatch& operator=(const BerkeleyBatch&) = delete; BerkeleyBatch& operator=(const BerkeleyBatch&) = delete;