| 449 | } |
| 450 | |
| 451 | bool BerkeleyDatabase::Rewrite(const char* pszSkip) |
| 452 | { |
| 453 | while (true) { |
| 454 | { |
| 455 | LOCK(cs_db); |
| 456 | if (m_refcount <= 0) { |
| 457 | // Flush log data to the dat file |
| 458 | env->CloseDb(strFile); |
| 459 | env->CheckpointLSN(strFile); |
| 460 | m_refcount = -1; |
| 461 | |
| 462 | bool fSuccess = true; |
| 463 | LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); |
| 464 | std::string strFileRes = strFile + ".rewrite"; |
| 465 | { // surround usage of db with extra {} |
| 466 | BerkeleyBatch db(*this, true); |
| 467 | std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0); |
| 468 | |
| 469 | int ret = pdbCopy->open(nullptr, // Txn pointer |
| 470 | strFileRes.c_str(), // Filename |
| 471 | "main", // Logical db name |
| 472 | DB_BTREE, // Database type |
| 473 | DB_CREATE, // Flags |
| 474 | 0); |
| 475 | if (ret > 0) { |
| 476 | LogPrintf("BerkeleyBatch::Rewrite: Can't create database file %s\n", strFileRes); |
| 477 | fSuccess = false; |
| 478 | } |
| 479 | |
| 480 | if (db.StartCursor()) { |
| 481 | while (fSuccess) { |
| 482 | CDataStream ssKey(SER_DISK, CLIENT_VERSION); |
| 483 | CDataStream ssValue(SER_DISK, CLIENT_VERSION); |
| 484 | bool complete; |
| 485 | bool ret1 = db.ReadAtCursor(ssKey, ssValue, complete); |
| 486 | if (complete) { |
| 487 | break; |
| 488 | } else if (!ret1) { |
| 489 | fSuccess = false; |
| 490 | break; |
| 491 | } |
| 492 | if (pszSkip && |
| 493 | strncmp((const char*)ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) |
| 494 | continue; |
| 495 | if (strncmp((const char*)ssKey.data(), "\x07version", 8) == 0) { |
| 496 | // Update version: |
| 497 | ssValue.clear(); |
| 498 | ssValue << CLIENT_VERSION; |
| 499 | } |
| 500 | Dbt datKey(ssKey.data(), ssKey.size()); |
| 501 | Dbt datValue(ssValue.data(), ssValue.size()); |
| 502 | int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, DB_NOOVERWRITE); |
| 503 | if (ret2 > 0) |
| 504 | fSuccess = false; |
| 505 | } |
| 506 | db.CloseCursor(); |
| 507 | } |
| 508 | if (fSuccess) { |
no test coverage detected