sift_core/search/emit/
stats.rs1use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
2use std::time::Duration;
3
4use grep_printer::Stats as JsonStats;
5
6#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
7pub struct SearchStats {
8 pub matches: usize,
9 pub files_with_matches: usize,
10 pub files_searched: usize,
11 pub bytes_printed: u64,
12 pub bytes_searched: u64,
13 pub elapsed: Duration,
14}
15
16impl SearchStats {
17 pub(crate) fn fill_from_json(
18 &mut self,
19 merged: &JsonStats,
20 candidates_len: usize,
21 bytes_searched_sum: u64,
22 elapsed: Duration,
23 summary_line_bytes: u64,
24 ) {
25 use std::convert::TryFrom;
26 self.matches = usize::try_from(merged.matches()).unwrap_or(usize::MAX);
27 self.files_with_matches =
28 usize::try_from(merged.searches_with_match()).unwrap_or(usize::MAX);
29 self.files_searched = candidates_len;
30 self.bytes_printed = merged.bytes_printed() + summary_line_bytes;
31 self.bytes_searched = bytes_searched_sum;
32 self.elapsed = elapsed;
33 }
34}
35
36#[derive(Debug)]
37pub struct TextStatsCounters {
38 primary: AtomicUsize,
39 files_with_matches: AtomicUsize,
40 bytes_printed: AtomicU64,
41 collect_stats: bool,
42}
43
44impl TextStatsCounters {
45 #[must_use]
46 pub const fn new(collect_stats: bool) -> Self {
47 Self {
48 primary: AtomicUsize::new(0),
49 files_with_matches: AtomicUsize::new(0),
50 bytes_printed: AtomicU64::new(0),
51 collect_stats,
52 }
53 }
54
55 pub fn primary(&self) -> Option<&AtomicUsize> {
56 self.collect_stats.then_some(&self.primary)
57 }
58
59 pub fn files_with_matches(&self) -> Option<&AtomicUsize> {
60 self.collect_stats.then_some(&self.files_with_matches)
61 }
62
63 pub fn bytes_printed(&self) -> Option<&AtomicU64> {
64 self.collect_stats.then_some(&self.bytes_printed)
65 }
66
67 pub fn finish(
68 self,
69 candidates_len: usize,
70 bytes_searched: u64,
71 elapsed: Duration,
72 ) -> Option<SearchStats> {
73 if !self.collect_stats {
74 return None;
75 }
76 Some(SearchStats {
77 matches: self.primary.load(Ordering::Relaxed),
78 files_with_matches: self.files_with_matches.load(Ordering::Relaxed),
79 files_searched: candidates_len,
80 bytes_printed: self.bytes_printed.load(Ordering::Relaxed),
81 bytes_searched,
82 elapsed,
83 })
84 }
85}