@@ -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 ()) {
0 commit comments