33using System . Collections . Immutable ;
44using System . IO ;
55using System . Linq ;
6+ using System . Text . RegularExpressions ;
67using BenchmarkDotNet . Analysers ;
78using BenchmarkDotNet . Characteristics ;
89using BenchmarkDotNet . Columns ;
@@ -42,6 +43,7 @@ internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)
4243 var rootArtifactsFolderPath = GetRootArtifactsFolderPath ( benchmarkRunInfos ) ;
4344 var resultsFolderPath = GetResultsFolderPath ( rootArtifactsFolderPath , benchmarkRunInfos ) ;
4445 var logFilePath = Path . Combine ( rootArtifactsFolderPath , title + ".log" ) ;
46+ var idToResume = GetIdToResume ( rootArtifactsFolderPath , title , benchmarkRunInfos ) ;
4547
4648 using ( var streamLogger = new StreamLogger ( GetLogFileStreamWriter ( benchmarkRunInfos , logFilePath ) ) )
4749 {
@@ -62,7 +64,7 @@ internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)
6264 return new [ ] { Summary . ValidationFailed ( title , resultsFolderPath , logFilePath ) } ;
6365
6466 int totalBenchmarkCount = supportedBenchmarks . Sum ( benchmarkInfo => benchmarkInfo . BenchmarksCases . Length ) ;
65- int benchmarksToRunCount = totalBenchmarkCount ;
67+ int benchmarksToRunCount = totalBenchmarkCount - ( idToResume + 1 ) ; // ids are indexed from 0
6668 compositeLogger . WriteLineHeader ( "// ***** BenchmarkRunner: Start *****" ) ;
6769 compositeLogger . WriteLineHeader ( $ "// ***** Found { totalBenchmarkCount } benchmark(s) in total *****") ;
6870 var globalChronometer = Chronometer . Start ( ) ;
@@ -84,6 +86,16 @@ internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)
8486
8587 foreach ( var benchmarkRunInfo in supportedBenchmarks ) // we run them in the old order now using the new build artifacts
8688 {
89+ if ( idToResume >= 0 )
90+ {
91+ var benchmarkWithHighestIdForGivenType = benchmarkRunInfo . BenchmarksCases . Last ( ) ;
92+ if ( benchmarkToBuildResult [ benchmarkWithHighestIdForGivenType ] . Id . Value <= idToResume )
93+ {
94+ compositeLogger . WriteLineInfo ( $ "Skipping { benchmarkRunInfo . BenchmarksCases . Length } benchmark(s) defined by { benchmarkRunInfo . Type . GetCorrectCSharpTypeName ( ) } .") ;
95+ continue ;
96+ }
97+ }
98+
8799 var summary = Run ( benchmarkRunInfo , benchmarkToBuildResult , resolver , compositeLogger , artifactsToCleanup ,
88100 resultsFolderPath , logFilePath , totalBenchmarkCount , in runsChronometer , ref benchmarksToRunCount ) ;
89101
@@ -678,5 +690,36 @@ private static void PrintValidationErrors(ILogger logger, IEnumerable<Validation
678690 logger . WriteLine ( ) ;
679691 }
680692 }
693+
694+ private static int GetIdToResume ( string rootArtifactsFolderPath , string currentLogFileName , BenchmarkRunInfo [ ] benchmarkRunInfos )
695+ {
696+ if ( benchmarkRunInfos . Any ( benchmark => benchmark . Config . Options . IsSet ( ConfigOptions . Resume ) ) )
697+ {
698+ var directoryInfo = new DirectoryInfo ( rootArtifactsFolderPath ) ;
699+ var logFilesExceptCurrent = directoryInfo
700+ . GetFiles ( $ "{ currentLogFileName . Split ( '-' ) [ 0 ] } *")
701+ . Where ( file => Path . GetFileNameWithoutExtension ( file . Name ) != currentLogFileName )
702+ . ToArray ( ) ;
703+
704+ if ( logFilesExceptCurrent . Length > 0 )
705+ {
706+ var previousRunLogFile = logFilesExceptCurrent
707+ . OrderByDescending ( o => o . LastWriteTime )
708+ . First ( ) ;
709+
710+ var regex = new Regex ( "--benchmarkId (.*?) in" , RegexOptions . Compiled ) ;
711+ foreach ( var line in File . ReadLines ( previousRunLogFile . FullName ) . Reverse ( ) )
712+ {
713+ var match = regex . Match ( line ) ;
714+ if ( match . Success )
715+ {
716+ return int . Parse ( match . Groups [ 1 ] . Value ) ;
717+ }
718+ }
719+ }
720+ }
721+
722+ return - 1 ;
723+ }
681724 }
682725}
0 commit comments