reifydb_core/metrics/
scan.rs1use std::cell::Cell;
5
6thread_local! {
7 static FETCHED: Cell<u64> = const { Cell::new(0) };
8 static TOMBSTONES: Cell<u64> = const { Cell::new(0) };
9}
10
11pub fn record_page(fetched: u64, tombstones: u64) {
12 FETCHED.with(|c| c.set(c.get().wrapping_add(fetched)));
13 TOMBSTONES.with(|c| c.set(c.get().wrapping_add(tombstones)));
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub struct ScanCounters {
18 pub fetched: u64,
19 pub tombstones: u64,
20}
21
22impl ScanCounters {
23 pub fn sample() -> Self {
24 Self {
25 fetched: FETCHED.with(|c| c.get()),
26 tombstones: TOMBSTONES.with(|c| c.get()),
27 }
28 }
29
30 pub fn since(self) -> Self {
31 let now = Self::sample();
32 Self {
33 fetched: now.fetched.wrapping_sub(self.fetched),
34 tombstones: now.tombstones.wrapping_sub(self.tombstones),
35 }
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn since_reports_only_what_the_caller_bracketed() {
45 record_page(100, 90);
49 let before = ScanCounters::sample();
50 record_page(7, 3);
51 let delta = before.since();
52
53 assert_eq!(delta.fetched, 7, "rows fetched before the bracket must not be attributed to it");
54 assert_eq!(delta.tombstones, 3);
55 }
56
57 #[test]
58 fn a_bracket_with_no_scan_reports_nothing() {
59 record_page(5, 5);
60 let before = ScanCounters::sample();
61
62 assert_eq!(
63 before.since(),
64 ScanCounters {
65 fetched: 0,
66 tombstones: 0
67 }
68 );
69 }
70}