| 382 | } |
| 383 | |
| 384 | bool CDB::Rewrite(const string& strFile, const char* pszSkip) |
| 385 | { |
| 386 | while (true) { |
| 387 | { |
| 388 | LOCK(bitdb.cs_db); |
| 389 | if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { |
| 390 | // Flush log data to the dat file |
| 391 | bitdb.CloseDb(strFile); |
| 392 | bitdb.CheckpointLSN(strFile); |
| 393 | bitdb.mapFileUseCount.erase(strFile); |
| 394 | |
| 395 | bool fSuccess = true; |
| 396 | LogPrintf("CDB::Rewrite : Rewriting %s...\n", strFile); |
| 397 | string strFileRes = strFile + ".rewrite"; |
| 398 | { // surround usage of db with extra {} |
| 399 | CDB db(strFile.c_str(), "r"); |
| 400 | Db* pdbCopy = new Db(bitdb.dbenv, 0); |
| 401 | |
| 402 | int ret = pdbCopy->open(NULL, // Txn pointer |
| 403 | strFileRes.c_str(), // Filename |
| 404 | "main", // Logical db name |
| 405 | DB_BTREE, // Database type |
| 406 | DB_CREATE, // Flags |
| 407 | 0); |
| 408 | if (ret > 0) { |
| 409 | LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes); |
| 410 | fSuccess = false; |
| 411 | } |
| 412 | |
| 413 | Dbc* pcursor = db.GetCursor(); |
| 414 | if (pcursor) |
| 415 | while (fSuccess) { |
| 416 | CDataStream ssKey(SER_DISK, CLIENT_VERSION); |
| 417 | CDataStream ssValue(SER_DISK, CLIENT_VERSION); |
| 418 | int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); |
| 419 | if (ret == DB_NOTFOUND) { |
| 420 | pcursor->close(); |
| 421 | break; |
| 422 | } else if (ret != 0) { |
| 423 | pcursor->close(); |
| 424 | fSuccess = false; |
| 425 | break; |
| 426 | } |
| 427 | if (pszSkip && |
| 428 | strncmp(ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) |
| 429 | continue; |
| 430 | if (strncmp(ssKey.data(), "\x07version", 8) == 0) { |
| 431 | // Update version: |
| 432 | ssValue.clear(); |
| 433 | ssValue << CLIENT_VERSION; |
| 434 | } |
| 435 | Dbt datKey(ssKey.data(), ssKey.size()); |
| 436 | Dbt datValue(ssValue.data(), ssValue.size()); |
| 437 | int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); |
| 438 | if (ret2 > 0) |
| 439 | fSuccess = false; |
| 440 | } |
| 441 | if (fSuccess) { |
nothing calls this directly
no test coverage detected