| 573 | } |
| 574 | |
| 575 | bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip) |
| 576 | { |
| 577 | if (database.IsDummy()) { |
| 578 | return true; |
| 579 | } |
| 580 | BerkeleyEnvironment *env = database.env; |
| 581 | const std::string& strFile = database.strFile; |
| 582 | while (true) { |
| 583 | { |
| 584 | LOCK(cs_db); |
| 585 | if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0) { |
| 586 | // Flush log data to the dat file |
| 587 | env->CloseDb(strFile); |
| 588 | env->CheckpointLSN(strFile); |
| 589 | env->mapFileUseCount.erase(strFile); |
| 590 | |
| 591 | bool fSuccess = true; |
| 592 | LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); |
| 593 | std::string strFileRes = strFile + ".rewrite"; |
| 594 | { // surround usage of db with extra {} |
| 595 | BerkeleyBatch db(database, "r"); |
| 596 | std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0); |
| 597 | |
| 598 | int ret = pdbCopy->open(nullptr, // Txn pointer |
| 599 | strFileRes.c_str(), // Filename |
| 600 | "main", // Logical db name |
| 601 | DB_BTREE, // Database type |
| 602 | DB_CREATE, // Flags |
| 603 | 0); |
| 604 | if (ret > 0) { |
| 605 | LogPrintf("BerkeleyBatch::Rewrite: Can't create database file %s\n", strFileRes); |
| 606 | fSuccess = false; |
| 607 | } |
| 608 | |
| 609 | Dbc* pcursor = db.GetCursor(); |
| 610 | if (pcursor) |
| 611 | while (fSuccess) { |
| 612 | CDataStream ssKey(SER_DISK, CLIENT_VERSION); |
| 613 | CDataStream ssValue(SER_DISK, CLIENT_VERSION); |
| 614 | int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue); |
| 615 | if (ret1 == DB_NOTFOUND) { |
| 616 | pcursor->close(); |
| 617 | break; |
| 618 | } else if (ret1 != 0) { |
| 619 | pcursor->close(); |
| 620 | fSuccess = false; |
| 621 | break; |
| 622 | } |
| 623 | if (pszSkip && |
| 624 | strncmp(ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) |
| 625 | continue; |
| 626 | if (strncmp(ssKey.data(), "\x07version", 8) == 0) { |
| 627 | // Update version: |
| 628 | ssValue.clear(); |
| 629 | ssValue << CLIENT_VERSION; |
| 630 | } |
| 631 | Dbt datKey(ssKey.data(), ssKey.size()); |
| 632 | Dbt datValue(ssValue.data(), ssValue.size()); |
no test coverage detected