Skip to main content

vortex_metrics/
histogram.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::sync::Arc;
5
6use parking_lot::RwLock;
7use sketches_ddsketch::DDSketch;
8
9/// Stores an arbitrary number of data points, giving approximated information about its distribution.
10/// The current implementation uses an implementation of the [DDSketch] type but that might change in the future.
11///
12/// [DDSketch]: https://arxiv.org/pdf/1908.10693
13#[derive(Default, Clone)]
14pub struct Histogram(Arc<RwLock<DDSketch>>);
15
16impl std::fmt::Debug for Histogram {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        f.debug_tuple("Histogram").finish_non_exhaustive()
19    }
20}
21
22impl Histogram {
23    pub(crate) fn new() -> Self {
24        Self(Default::default())
25    }
26
27    /// Adds a sample to the histogram
28    pub fn update(&self, value: f64) {
29        self.0.write().add(value);
30    }
31
32    /// Returns the estimated quantile value, which must be in the [0.0, 1.0] range, will panic otherwise.
33    /// Returns `None` if the histogram is empty.
34    #[allow(clippy::expect_used)]
35    #[allow(clippy::unwrap_in_result)]
36    pub fn quantile(&self, quantile: f64) -> Option<f64> {
37        assert!(
38            (0.0..=1.0).contains(&quantile),
39            "quantile must be between 0.0 and 1.0"
40        );
41
42        self.0
43            .read()
44            .quantile(quantile)
45            .expect("quantile range checked")
46    }
47
48    /// Returns the sum of all values stored in the histogram
49    pub fn total(&self) -> f64 {
50        self.0.read().sum().unwrap_or_default()
51    }
52
53    /// Returns the number of values recorded.
54    pub fn count(&self) -> usize {
55        self.0.read().count()
56    }
57
58    /// Returns true if the histogram contains 0 samples.
59    pub fn is_empty(&self) -> bool {
60        self.0.read().count() == 0
61    }
62}