@@ -18,7 +18,8 @@ use log::debug;
1818use memchr:: memchr;
1919
2020use super :: {
21- BackendCapabilities , FileViewerBackend , LineChunk , MAX_BACKWARD_SCAN , SearchMatch , SeekTarget , ViewerError ,
21+ BackendCapabilities , FileViewerBackend , LineChunk , MAX_BACKWARD_SCAN , MAX_SEARCH_MATCHES , SearchMatch , SeekTarget ,
22+ ViewerError ,
2223} ;
2324
2425pub struct ByteSeekBackend {
@@ -223,6 +224,7 @@ impl FileViewerBackend for ByteSeekBackend {
223224 let mut line_number: usize = 0 ;
224225 let mut scanned: u64 = 0 ;
225226 let mut leftover = Vec :: new ( ) ;
227+ let mut limit_reached = false ;
226228
227229 loop {
228230 if cancel. load ( Ordering :: Relaxed ) {
@@ -253,22 +255,30 @@ impl FileViewerBackend for ByteSeekBackend {
253255 }
254256
255257 if let Some ( nl_pos) = memchr ( b'\n' , & data[ pos..] ) {
256- let line_bytes = & data[ pos..pos + nl_pos] ;
257- let line = String :: from_utf8_lossy ( line_bytes) ;
258- let line_lower = line. to_lowercase ( ) ;
259-
260- let mut search_start = 0 ;
261- while let Some ( match_pos) = line_lower[ search_start..] . find ( & query_lower) {
262- let col_bytes = search_start + match_pos;
263- let col_utf16: usize = line_lower[ ..col_bytes] . chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
264- let len_utf16: usize = query_lower. chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
265- let mut matches = results. lock_ignore_poison ( ) ;
266- matches. push ( SearchMatch {
267- line : line_number,
268- column : col_utf16,
269- length : len_utf16,
270- } ) ;
271- search_start = col_bytes + query_lower. len ( ) ;
258+ // Only do the expensive match-finding if we haven't hit the limit
259+ if !limit_reached {
260+ let line_bytes = & data[ pos..pos + nl_pos] ;
261+ let line = String :: from_utf8_lossy ( line_bytes) ;
262+ let line_lower = line. to_lowercase ( ) ;
263+
264+ let mut search_start = 0 ;
265+ while let Some ( match_pos) = line_lower[ search_start..] . find ( & query_lower) {
266+ let col_bytes = search_start + match_pos;
267+ let col_utf16: usize =
268+ line_lower[ ..col_bytes] . chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
269+ let len_utf16: usize = query_lower. chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
270+ let mut matches = results. lock_ignore_poison ( ) ;
271+ matches. push ( SearchMatch {
272+ line : line_number,
273+ column : col_utf16,
274+ length : len_utf16,
275+ } ) ;
276+ if matches. len ( ) >= MAX_SEARCH_MATCHES {
277+ limit_reached = true ;
278+ break ;
279+ }
280+ search_start = col_bytes + query_lower. len ( ) ;
281+ }
272282 }
273283
274284 scanned += ( nl_pos + 1 ) as u64 ;
@@ -287,20 +297,25 @@ impl FileViewerBackend for ByteSeekBackend {
287297
288298 // Handle last line without newline
289299 if !leftover. is_empty ( ) {
290- let line = String :: from_utf8_lossy ( & leftover) ;
291- let line_lower = line. to_lowercase ( ) ;
292- let mut search_start = 0 ;
293- while let Some ( match_pos) = line_lower[ search_start..] . find ( & query_lower) {
294- let col_bytes = search_start + match_pos;
295- let col_utf16: usize = line_lower[ ..col_bytes] . chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
296- let len_utf16: usize = query_lower. chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
297- let mut matches = results. lock_ignore_poison ( ) ;
298- matches. push ( SearchMatch {
299- line : line_number,
300- column : col_utf16,
301- length : len_utf16,
302- } ) ;
303- search_start = col_bytes + query_lower. len ( ) ;
300+ if !limit_reached {
301+ let line = String :: from_utf8_lossy ( & leftover) ;
302+ let line_lower = line. to_lowercase ( ) ;
303+ let mut search_start = 0 ;
304+ while let Some ( match_pos) = line_lower[ search_start..] . find ( & query_lower) {
305+ let col_bytes = search_start + match_pos;
306+ let col_utf16: usize = line_lower[ ..col_bytes] . chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
307+ let len_utf16: usize = query_lower. chars ( ) . map ( |c| c. len_utf16 ( ) ) . sum ( ) ;
308+ let mut matches = results. lock_ignore_poison ( ) ;
309+ matches. push ( SearchMatch {
310+ line : line_number,
311+ column : col_utf16,
312+ length : len_utf16,
313+ } ) ;
314+ if matches. len ( ) >= MAX_SEARCH_MATCHES {
315+ break ;
316+ }
317+ search_start = col_bytes + query_lower. len ( ) ;
318+ }
304319 }
305320 scanned += leftover. len ( ) as u64 ;
306321 }
0 commit comments