diff --git a/src/dbwrapper.h b/src/dbwrapper.h --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -311,6 +311,22 @@ pdb->GetApproximateSizes(&range, 1, &size); return size; } + + /** + * Compact a certain range of keys in the database. + */ + template + void CompactRange(const K &key_begin, const K &key_end) const { + CDataStream ssKey1(SER_DISK, CLIENT_VERSION), + ssKey2(SER_DISK, CLIENT_VERSION); + ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); + ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE); + ssKey1 << key_begin; + ssKey2 << key_end; + leveldb::Slice slKey1(ssKey1.data(), ssKey1.size()); + leveldb::Slice slKey2(ssKey2.data(), ssKey2.size()); + pdb->CompactRange(&slKey1, &slKey2); + } }; #endif // BITCOIN_DBWRAPPER_H diff --git a/src/txdb.cpp b/src/txdb.cpp --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -343,13 +343,14 @@ CDBBatch batch(db); uiInterface.SetProgressBreakAction(StartShutdown); int reportDone = 0; + std::pair key; + std::pair prev_key = {DB_COINS, uint256()}; while (pcursor->Valid()) { boost::this_thread::interruption_point(); if (ShutdownRequested()) { break; } - std::pair key; if (!pcursor->GetKey(key) || key.first != DB_COINS) { break; } @@ -390,12 +391,15 @@ if (batch.SizeEstimate() > batch_size) { db.WriteBatch(batch); batch.Clear(); + db.CompactRange(prev_key, key); + prev_key = key; } pcursor->Next(); } db.WriteBatch(batch); + db.CompactRange({DB_COINS, uint256()}, key); uiInterface.SetProgressBreakAction(std::function()); LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE"); return !ShutdownRequested();