diff options
Diffstat (limited to 'src/db.h')
-rw-r--r-- | src/db.h | 93 |
1 files changed, 60 insertions, 33 deletions
@@ -25,21 +25,56 @@ 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; + std::map<std::string, int> mapFileUseCount; + std::map<std::string, Db*> mapDb; + + 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_; } + + void CloseDb(const std::string& strFile); + + DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) + { + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(NULL, &ptxn, flags); + if (!ptxn || ret != 0) + return NULL; + return ptxn; + } +}; + +extern CDBEnv bitdb; + + /** RAII class that provides access to a Berkeley database */ class CDB { protected: Db* pdb; std::string strFile; - std::vector<DbTxn*> vTxn; + DbTxn *activeTxn; bool fReadOnly; explicit CDB(const char* pszFile, const char* pszMode="r+"); @@ -66,14 +101,19 @@ 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; // Unserialize value - CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); - ssValue >> value; + try { + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); + ssValue >> value; + } + catch (std::exception &e) { + return false; + } // Clear and free memory memset(datValue.get_data(), 0, datValue.get_size()); @@ -102,7 +142,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()); @@ -125,7 +165,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()); @@ -145,7 +185,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()); @@ -202,46 +242,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 = NULL; - int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC); - if (!ptxn || ret != 0) + DbTxn* ptxn = bitdb.TxnBegin(); + if (!ptxn) return false; - vTxn.push_back(ptxn); + activeTxn = ptxn; return true; } bool TxnCommit() { - if (!pdb) + if (!pdb || !activeTxn) return false; - if (vTxn.empty()) - 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); } |