@@ -90,7 +90,13 @@ Common options:
9090 -q, --quiet Do not return number of matches to stderr.
9191"# ;
9292
93- use std:: { fs, sync:: Arc } ;
93+ use std:: {
94+ fs,
95+ sync:: {
96+ Arc ,
97+ atomic:: { AtomicBool , Ordering } ,
98+ } ,
99+ } ;
94100
95101use crossbeam_channel;
96102#[ cfg( any( feature = "feature_capable" , feature = "lite" ) ) ]
@@ -543,18 +549,23 @@ impl Args {
543549 // Wrap pattern in Arc for sharing across threads
544550 let pattern = Arc :: new ( pattern) ;
545551 let invert_match = self . flag_invert_match ;
552+ let flag_quick = self . flag_quick ;
553+
554+ // Atomic flag for early termination in quick mode
555+ let match_found = Arc :: new ( AtomicBool :: new ( false ) ) ;
546556
547557 // Create thread pool and channel
548558 let pool = ThreadPool :: new ( njobs) ;
549559 let ( send, recv) = crossbeam_channel:: bounded ( nchunks) ;
550560
551561 // Spawn search jobs
552562 for i in 0 ..nchunks {
553- let ( send, args, sel, pattern) = (
563+ let ( send, args, sel, pattern, match_found_flag ) = (
554564 send. clone ( ) ,
555565 self . clone ( ) ,
556566 sel. clone ( ) ,
557567 Arc :: clone ( & pattern) ,
568+ Arc :: clone ( & match_found) ,
558569 ) ;
559570 pool. execute ( move || {
560571 // safety: we know the file is indexed and seekable
@@ -566,17 +577,33 @@ impl Args {
566577 let mut row_number = ( i * chunk_size) as u64 + 1 ; // 1-based row numbering
567578
568579 for record in it. flatten ( ) {
580+ // Early exit for quick mode if match already found by another thread
581+ if flag_quick && match_found_flag. load ( Ordering :: Relaxed ) {
582+ break ;
583+ }
584+
569585 let matched = if invert_match {
570586 !sel. select ( & record) . any ( |f| pattern. is_match ( f) )
571587 } else {
572588 sel. select ( & record) . any ( |f| pattern. is_match ( f) )
573589 } ;
590+
591+ // Set flag if we found a match in quick mode
592+ if flag_quick && matched {
593+ match_found_flag. store ( true , Ordering :: Relaxed ) ;
594+ }
595+
574596 results. push ( SearchResult {
575597 row_number,
576598 record,
577599 matched,
578600 } ) ;
579601 row_number += 1 ;
602+
603+ // Early exit after finding first match in quick mode
604+ if flag_quick && matched {
605+ break ;
606+ }
580607 }
581608 send. send ( results) . unwrap ( ) ;
582609 } ) ;
0 commit comments