Skip to content

Commit 1fc1b85

Browse files
committed
refactor: search optimize --quick option
1 parent c4ce324 commit 1fc1b85

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

src/cmd/search.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

95101
use 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

Comments
 (0)