Skip to main content

relay_cogs/
measurement.rs

1use crate::time::{Clock, Duration, Instant};
2
3/// Simple collection of individual measurements.
4///
5/// Tracks the total time from starting the measurements as well as
6/// individual categorized measurements.
7pub struct Measurements<C> {
8    start: Instant,
9    categorized: Vec<Measurement>,
10    clock: C,
11}
12
13impl<C> Measurements<C>
14where
15    C: Clock,
16{
17    /// Starts recording the first measurement.
18    pub fn start(clock: C) -> Self {
19        Measurements {
20            start: clock.now(),
21            categorized: Vec::new(),
22            clock,
23        }
24    }
25
26    /// Starts a categorized measurement, which can be finalized with [`Self::finish_category`].
27    pub fn start_category(&self) -> CatgegoryMeasurement {
28        CatgegoryMeasurement {
29            start: self.clock.now(),
30        }
31    }
32
33    /// Finishes an individual categorized measurement, started with [`Self::start_category`].
34    pub fn finish_category(&mut self, measurement: CatgegoryMeasurement, category: &'static str) {
35        self.categorized.push(Measurement {
36            duration: self.clock.now().since(measurement.start),
37            category: Some(category),
38        });
39    }
40
41    /// Finishes the current measurements and returns all individual
42    /// categorized measurements.
43    pub fn finish(&self) -> impl Iterator<Item = Measurement> + '_ {
44        let mut duration = self.clock.now().since(self.start);
45        for c in &self.categorized {
46            duration = duration.saturating_sub(c.duration);
47        }
48
49        std::iter::once(Measurement {
50            duration,
51            category: None,
52        })
53        .chain(self.categorized.iter().copied())
54        .filter(|m| !m.duration.is_zero())
55    }
56}
57
58/// A single, optionally, categorized measurement.
59#[derive(Copy, Clone)]
60pub struct Measurement {
61    /// Length of the measurement.
62    pub duration: Duration,
63    /// Optional category, if the measurement was categorized.
64    pub category: Option<&'static str>,
65}
66
67/// An individual categorized measurement started with [`Measurements::start_category`].
68#[derive(Clone, Copy)]
69pub struct CatgegoryMeasurement {
70    start: Instant,
71}