relay_cogs/measurement.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
use crate::time::{Duration, Instant};
/// Simple collection of individual measurements.
///
/// Tracks the total time from starting the measurements as well as
/// individual categorized measurements.
pub struct Measurements {
start: Instant,
categorized: Vec<Measurement>,
}
impl Measurements {
/// Starts recording the first measurement.
pub fn start() -> Self {
Measurements {
start: Instant::now(),
categorized: Vec::new(),
}
}
/// Adds an individual categorized measurement.
pub fn add(&mut self, duration: Duration, category: &'static str) {
self.categorized.push(Measurement {
duration,
category: Some(category),
});
}
/// Finishes the current measurements and returns all individual
/// categorized measurements.
pub fn finish(&self) -> impl Iterator<Item = Measurement> + '_ {
let mut duration = self.start.elapsed();
for c in &self.categorized {
duration = duration.saturating_sub(c.duration);
}
std::iter::once(Measurement {
duration,
category: None,
})
.chain(self.categorized.iter().copied())
.filter(|m| !m.duration.is_zero())
}
}
/// A single, optionally, categorized measurement.
#[derive(Copy, Clone)]
pub struct Measurement {
/// Length of the measurement.
pub duration: Duration,
/// Optional category, if the measurement was categorized.
pub category: Option<&'static str>,
}