Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/bdb.cpp
Show First 20 Lines • Show All 330 Lines • ▼ Show 20 Lines | void BerkeleyEnvironment::CheckpointLSN(const std::string &strFile) { | ||||
if (fMockDb) { | if (fMockDb) { | ||||
return; | return; | ||||
} | } | ||||
dbenv->lsn_reset(strFile.c_str(), 0); | dbenv->lsn_reset(strFile.c_str(), 0); | ||||
} | } | ||||
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase &database, const char *pszMode, | BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase &database, const char *pszMode, | ||||
bool fFlushOnCloseIn) | bool fFlushOnCloseIn) | ||||
: pdb(nullptr), activeTxn(nullptr) { | : pdb(nullptr), activeTxn(nullptr), m_cursor(nullptr) { | ||||
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()) { | if (database.IsDummy()) { | ||||
return; | return; | ||||
} | } | ||||
const std::string &strFilename = database.strFile; | const std::string &strFilename = database.strFile; | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | void BerkeleyBatch::Close() { | ||||
if (!pdb) { | if (!pdb) { | ||||
return; | return; | ||||
} | } | ||||
if (activeTxn) { | if (activeTxn) { | ||||
activeTxn->abort(); | activeTxn->abort(); | ||||
} | } | ||||
activeTxn = nullptr; | activeTxn = nullptr; | ||||
pdb = nullptr; | pdb = nullptr; | ||||
CloseCursor(); | |||||
if (fFlushOnClose) { | if (fFlushOnClose) { | ||||
Flush(); | Flush(); | ||||
} | } | ||||
{ | { | ||||
LOCK(cs_db); | LOCK(cs_db); | ||||
--env->mapFileUseCount[strFile]; | --env->mapFileUseCount[strFile]; | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | while (true) { | ||||
0); | 0); | ||||
if (ret > 0) { | if (ret > 0) { | ||||
LogPrintf("BerkeleyBatch::Rewrite: Can't create " | LogPrintf("BerkeleyBatch::Rewrite: Can't create " | ||||
"database file %s\n", | "database file %s\n", | ||||
strFileRes); | strFileRes); | ||||
fSuccess = false; | fSuccess = false; | ||||
} | } | ||||
Dbc *pcursor = db.GetCursor(); | if (db.StartCursor()) { | ||||
if (pcursor) { | |||||
while (fSuccess) { | while (fSuccess) { | ||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION); | CDataStream ssKey(SER_DISK, CLIENT_VERSION); | ||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION); | CDataStream ssValue(SER_DISK, CLIENT_VERSION); | ||||
int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue); | bool complete; | ||||
if (ret1 == DB_NOTFOUND) { | bool ret1 = | ||||
pcursor->close(); | db.ReadAtCursor(ssKey, ssValue, complete); | ||||
if (complete) { | |||||
break; | break; | ||||
} | } | ||||
if (ret1 != 0) { | if (!ret1) { | ||||
pcursor->close(); | |||||
fSuccess = false; | fSuccess = false; | ||||
break; | break; | ||||
} | } | ||||
if (pszSkip && | if (pszSkip && | ||||
strncmp(ssKey.data(), pszSkip, | strncmp(ssKey.data(), pszSkip, | ||||
std::min(ssKey.size(), | std::min(ssKey.size(), | ||||
strlen(pszSkip))) == 0) { | strlen(pszSkip))) == 0) { | ||||
continue; | continue; | ||||
} | } | ||||
if (strncmp(ssKey.data(), "\x07version", 8) == 0) { | if (strncmp(ssKey.data(), "\x07version", 8) == 0) { | ||||
// Update version: | // Update version: | ||||
ssValue.clear(); | ssValue.clear(); | ||||
ssValue << CLIENT_VERSION; | ssValue << CLIENT_VERSION; | ||||
} | } | ||||
Dbt datKey(ssKey.data(), ssKey.size()); | Dbt datKey(ssKey.data(), ssKey.size()); | ||||
Dbt datValue(ssValue.data(), ssValue.size()); | Dbt datValue(ssValue.data(), ssValue.size()); | ||||
int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, | int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, | ||||
DB_NOOVERWRITE); | DB_NOOVERWRITE); | ||||
if (ret2 > 0) { | if (ret2 > 0) { | ||||
fSuccess = false; | fSuccess = false; | ||||
} | } | ||||
} | } | ||||
db.CloseCursor(); | |||||
} | } | ||||
if (fSuccess) { | if (fSuccess) { | ||||
db.Close(); | db.Close(); | ||||
env->CloseDb(strFile); | env->CloseDb(strFile); | ||||
if (pdbCopy->close(0)) { | if (pdbCopy->close(0)) { | ||||
fSuccess = false; | fSuccess = false; | ||||
} | } | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void BerkeleyDatabase::ReloadDbEnv() { | void BerkeleyDatabase::ReloadDbEnv() { | ||||
if (!IsDummy()) { | if (!IsDummy()) { | ||||
env->ReloadDbEnv(); | env->ReloadDbEnv(); | ||||
} | } | ||||
} | } | ||||
Dbc *BerkeleyBatch::GetCursor() { | bool BerkeleyBatch::StartCursor() { | ||||
assert(!m_cursor); | |||||
if (!pdb) { | if (!pdb) { | ||||
return nullptr; | return false; | ||||
} | |||||
Dbc *pcursor = nullptr; | |||||
int ret = pdb->cursor(nullptr, &pcursor, 0); | |||||
if (ret != 0) { | |||||
return nullptr; | |||||
} | } | ||||
return pcursor; | int ret = pdb->cursor(nullptr, &m_cursor, 0); | ||||
return ret == 0; | |||||
} | } | ||||
int BerkeleyBatch::ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, | bool BerkeleyBatch::ReadAtCursor(CDataStream &ssKey, CDataStream &ssValue, | ||||
CDataStream &ssValue) { | bool &complete) { | ||||
complete = false; | |||||
if (m_cursor == nullptr) { | |||||
return false; | |||||
} | |||||
// Read at cursor | // Read at cursor | ||||
SafeDbt datKey; | SafeDbt datKey; | ||||
SafeDbt datValue; | SafeDbt datValue; | ||||
int ret = pcursor->get(datKey, datValue, DB_NEXT); | int ret = m_cursor->get(datKey, datValue, DB_NEXT); | ||||
if (ret == DB_NOTFOUND) { | |||||
complete = true; | |||||
} | |||||
if (ret != 0) { | if (ret != 0) { | ||||
return ret; | return false; | ||||
} else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr) { | } else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr) { | ||||
return 99999; | return false; | ||||
} | } | ||||
// Convert to streams | // Convert to streams | ||||
ssKey.SetType(SER_DISK); | ssKey.SetType(SER_DISK); | ||||
ssKey.clear(); | ssKey.clear(); | ||||
ssKey.write((char *)datKey.get_data(), datKey.get_size()); | ssKey.write((char *)datKey.get_data(), datKey.get_size()); | ||||
ssValue.SetType(SER_DISK); | ssValue.SetType(SER_DISK); | ||||
ssValue.clear(); | ssValue.clear(); | ||||
ssValue.write((char *)datValue.get_data(), datValue.get_size()); | ssValue.write((char *)datValue.get_data(), datValue.get_size()); | ||||
return 0; | return true; | ||||
} | |||||
void BerkeleyBatch::CloseCursor() { | |||||
if (!m_cursor) { | |||||
return; | |||||
} | |||||
m_cursor->close(); | |||||
m_cursor = nullptr; | |||||
} | } | ||||
bool BerkeleyBatch::TxnBegin() { | bool BerkeleyBatch::TxnBegin() { | ||||
if (!pdb || activeTxn) { | if (!pdb || activeTxn) { | ||||
return false; | return false; | ||||
} | } | ||||
DbTxn *ptxn = env->TxnBegin(); | DbTxn *ptxn = env->TxnBegin(); | ||||
if (!ptxn) { | if (!ptxn) { | ||||
▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines |