Skip to content

Commit dd8fe82

Browse files
committed
Merge pull request #6221
c257a8c Prune: Support noncontiguous block files (Adam Weiss)
2 parents 51870fc + c257a8c commit dd8fe82

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

src/init.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -474,24 +474,43 @@ struct CImportingNow
474474

475475
// If we're using -prune with -reindex, then delete block files that will be ignored by the
476476
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
477-
// is missing, and since pruning works by deleting the oldest block file first, just check
478-
// for block file 0, and if it doesn't exist, delete all the block files in the
479-
// directory (since they won't be read by the reindex but will take up disk space).
480-
void DeleteAllBlockFiles()
477+
// is missing, do the same here to delete any later block files after a gap. Also delete all
478+
// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
479+
// is in sync with what's actually on disk by the time we start downloading, so that pruning
480+
// works correctly.
481+
void CleanupBlockRevFiles()
481482
{
482-
if (boost::filesystem::exists(GetBlockPosFilename(CDiskBlockPos(0, 0), "blk")))
483-
return;
483+
using namespace boost::filesystem;
484+
map<string, path> mapBlockFiles;
485+
486+
// Glob all blk?????.dat and rev?????.dat files from the blocks directory.
487+
// Remove the rev files immediately and insert the blk file paths into an
488+
// ordered map keyed by block file index.
489+
LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
490+
path blocksdir = GetDataDir() / "blocks";
491+
for (directory_iterator it(blocksdir); it != directory_iterator(); it++) {
492+
if (is_regular_file(*it) &&
493+
it->path().filename().string().length() == 12 &&
494+
it->path().filename().string().substr(8,4) == ".dat")
495+
{
496+
if (it->path().filename().string().substr(0,3) == "blk")
497+
mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
498+
else if (it->path().filename().string().substr(0,3) == "rev")
499+
remove(it->path());
500+
}
501+
}
484502

485-
LogPrintf("Removing all blk?????.dat and rev?????.dat files for -reindex with -prune\n");
486-
boost::filesystem::path blocksdir = GetDataDir() / "blocks";
487-
for (boost::filesystem::directory_iterator it(blocksdir); it != boost::filesystem::directory_iterator(); it++) {
488-
if (is_regular_file(*it)) {
489-
if ((it->path().filename().string().length() == 12) &&
490-
(it->path().filename().string().substr(8,4) == ".dat") &&
491-
((it->path().filename().string().substr(0,3) == "blk") ||
492-
(it->path().filename().string().substr(0,3) == "rev")))
493-
boost::filesystem::remove(it->path());
503+
// Remove all block files that aren't part of a contiguous set starting at
504+
// zero by walking the ordered map (keys are block file indices) by
505+
// keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
506+
// start removing block files.
507+
int nContigCounter = 0;
508+
BOOST_FOREACH(const PAIRTYPE(string, path)& item, mapBlockFiles) {
509+
if (atoi(item.first) == nContigCounter) {
510+
nContigCounter++;
511+
continue;
494512
}
513+
remove(item.second);
495514
}
496515
}
497516

@@ -1107,9 +1126,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
11071126

11081127
if (fReindex) {
11091128
pblocktree->WriteReindexing(true);
1110-
//If we're reindexing in prune mode, wipe away all our block and undo data files
1129+
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
11111130
if (fPruneMode)
1112-
DeleteAllBlockFiles();
1131+
CleanupBlockRevFiles();
11131132
}
11141133

11151134
if (!LoadBlockIndex()) {

src/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3057,9 +3057,9 @@ void FindFilesToPrune(std::set<int>& setFilesToPrune)
30573057
if (nCurrentUsage + nBuffer < nPruneTarget) // are we below our target?
30583058
break;
30593059

3060-
// don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip
3060+
// don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
30613061
if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
3062-
break;
3062+
continue;
30633063

30643064
PruneOneBlockFile(fileNumber);
30653065
// Queue up the files for removal

0 commit comments

Comments
 (0)