@@ -9,6 +9,8 @@ public class GitContentSearcher : IGitContentSearcher
99 private readonly IFileManager _fileManager ;
1010 private readonly TextWriter _logWriter ;
1111 private readonly bool _disableLinearSearch ;
12+ private IProgress < double > ? _progress ;
13+ private double _currentProgress = 0 ;
1214
1315 public GitContentSearcher ( IGitHelper gitHelper , IFileSearcher fileSearcher , IFileManager fileManager , bool disableLinearSearch , TextWriter ? logWriter = null )
1416 {
@@ -37,8 +39,12 @@ private bool FileExistsInCurrentCommit(string filePath)
3739 }
3840 }
3941
40- public void SearchContent ( string filePath , string searchString , string earliestCommit = "" , string latestCommit = "" )
42+ public void SearchContent ( string filePath , string searchString , string earliestCommit = "" , string latestCommit = "" , IProgress < double > ? progress = null )
4143 {
44+ _progress = progress ;
45+ _currentProgress = 0 ;
46+ _progress ? . Report ( 0.05 ) ; // Initial 5% progress to show activity
47+
4248 if ( ! FileExistsInCurrentCommit ( filePath ) )
4349 {
4450 _logWriter . WriteLine ( $ "Warning: The file '{ filePath } ' does not exist in the current commit.") ;
@@ -53,12 +59,16 @@ public void SearchContent(string filePath, string searchString, string earliestC
5359 if ( commits == null || commits . Count == 0 )
5460 {
5561 _logWriter . WriteLine ( "No commits found in the specified range." ) ;
62+ _progress ? . Report ( 1.0 ) ;
5663 return ;
5764 }
5865
66+ _progress ? . Report ( 0.25 ) ; // Commits retrieved
67+
5968 if ( commits . FindIndex ( c => c . CommitHash == earliestCommit ) > commits . FindIndex ( c => c . CommitHash == latestCommit ) )
6069 {
6170 _logWriter . WriteLine ( "Error: The earliest commit is more recent than the latest commit." ) ;
71+ _progress ? . Report ( 1.0 ) ;
6272 return ;
6373 }
6474
@@ -69,13 +79,18 @@ public void SearchContent(string filePath, string searchString, string earliestC
6979 int firstMatchIndex = FindFirstMatchIndex ( commits , filePath , searchString , lastMatchIndex ) ;
7080
7181 LogResults ( firstMatchIndex , lastMatchIndex , commits , searchString ) ;
82+
83+ _progress ? . Report ( 1.0 ) ;
7284 }
7385
7486 private int FindFirstMatchIndex ( List < Commit > commits , string filePath , string searchString , int lastMatchIndex )
7587 {
7688 int left = 0 ;
7789 int right = lastMatchIndex ; // Use lastMatchIndex as the upper bound
7890 int ? firstMatchIndex = null ;
91+ // For binary search, we'll make approximately log2(n) comparisons
92+ int expectedSearches = ( int ) Math . Ceiling ( Math . Log2 ( Math . Max ( 1 , right - left + 1 ) ) ) ;
93+ int searchesDone = 0 ;
7994
8095 while ( left <= right )
8196 {
@@ -100,6 +115,12 @@ private int FindFirstMatchIndex(List<Commit> commits, string filePath, string se
100115 _logWriter . WriteLine ( $ "Checked commit: { commit . CommitHash } at { commitTime } , found: { found } ") ;
101116 _logWriter . Flush ( ) ;
102117
118+ searchesDone ++ ;
119+ // Calculate progress between 62.5% and 100%
120+ double searchProgress = ( double ) searchesDone / expectedSearches ;
121+ _currentProgress = 0.625 + ( searchProgress * 0.375 ) ;
122+ _progress ? . Report ( _currentProgress ) ;
123+
103124 if ( found )
104125 {
105126 firstMatchIndex = mid ;
@@ -121,6 +142,9 @@ private int FindLastMatchIndex(List<Commit> commits, string filePath, string sea
121142 int left = searchStartIndex == - 1 ? 0 : searchStartIndex ;
122143 int right = commits . Count - 1 ;
123144 int ? lastMatchIndex = null ;
145+ // For binary search, we'll make approximately log2(n) comparisons
146+ int expectedSearches = ( int ) Math . Ceiling ( Math . Log2 ( Math . Max ( 1 , right - left + 1 ) ) ) ;
147+ int searchesDone = 0 ;
124148
125149 while ( left <= right )
126150 {
@@ -145,6 +169,12 @@ private int FindLastMatchIndex(List<Commit> commits, string filePath, string sea
145169 _logWriter . WriteLine ( $ "Checked commit: { commit . CommitHash } at { commitTime } , found: { found } ") ;
146170 _logWriter . Flush ( ) ;
147171
172+ searchesDone ++ ;
173+ // Calculate progress between 25% and 62.5%
174+ double searchProgress = ( double ) searchesDone / expectedSearches ;
175+ _currentProgress = 0.25 + ( searchProgress * 0.375 ) ;
176+ _progress ? . Report ( _currentProgress ) ;
177+
148178 if ( found )
149179 {
150180 lastMatchIndex = mid ;
@@ -159,6 +189,9 @@ private int FindLastMatchIndex(List<Commit> commits, string filePath, string sea
159189 if ( linearSearchResult . HasValue )
160190 {
161191 lastMatchIndex = linearSearchResult ;
192+ // Update progress to 62.5% since we're done with this phase
193+ _currentProgress = 0.625 ;
194+ _progress ? . Report ( _currentProgress ) ;
162195 break ;
163196 }
164197 }
@@ -177,6 +210,8 @@ private int FindLastMatchIndex(List<Commit> commits, string filePath, string sea
177210 int step = reverse ? - 1 : 1 ; // Use step to control direction of iteration
178211 int start = reverse ? right : left ;
179212 int end = reverse ? left : right ;
213+ int totalSearches = Math . Abs ( end - start ) + 1 ;
214+ int searchesDone = 0 ;
180215
181216 for ( int i = start ; reverse ? i >= end : i <= end ; i += step )
182217 {
@@ -200,6 +235,12 @@ private int FindLastMatchIndex(List<Commit> commits, string filePath, string sea
200235 _logWriter . WriteLine ( $ "Checked commit: { commit . CommitHash } at { commitTime } , found: { found } ") ;
201236 _logWriter . Flush ( ) ;
202237
238+ searchesDone ++ ;
239+ // Calculate progress for linear search portion
240+ double searchProgress = ( double ) searchesDone / totalSearches ;
241+ _currentProgress = 0.25 + ( searchProgress * 0.375 ) ;
242+ _progress ? . Report ( _currentProgress ) ;
243+
203244 _fileManager . DeleteTempFile ( tempFileName ) ; // Always clean up the temp file
204245
205246 if ( found )
0 commit comments