Repository: tokio-rs/tokio
File: tokio/src/runtime/metrics/histogram/h2_histogram.rs (Rust)

Code before:
/// 3. `precision`: max error of 25%
///
/// This uses 237 64-bit buckets.
#[derive(Default, Debug, Copy, Clone)]
pub struct LogHistogramBuilder {
    max_value: Option<Duration>,
    min_value: Option<Duration>,
    precision: Option<u32>,
}

impl From<LogHistogramBuilder> for LogHistogram {
    fn from(value: LogHistogramBuilder) -> Self {
        value.build()
    }
}

impl LogHistogramBuilder {
    /// Set the precision for this histogram
    ///
    /// This function determines the smallest value of `p` that would satisfy the requested precision
    /// such that `2^-p` is less than `precision`. To set `p` directly, use
    /// [`LogHistogramBuilder::precision_exact`].
    ///
    /// To match the behavior of the previous log histogram implementation, use
    /// `builder.precision_exact(0)`. This creates a histogram where each bucket is twice the size
    /// of the previous value.
    ///
    /// The default value is 25% (2^-2)
    ///
    /// The highest supported precision is `0.0977%` `(2^-10)`. Provided values
    /// less than this will be truncated.
    ///
    /// # Panics
    /// - `precision` < 0
    /// - `precision` > 1
    pub fn max_error(mut self, max_error: f64) -> Self {
        if max_error < 0.0 {
            panic!("precision must be >= 0");
        };
        if max_error > 1.0 {
            panic!("precision must be > 1");
        };
        let mut p = 2;
        while 2_f64.powf(-1.0 * p as f64) > max_error && p <= MAX_PRECISION {
            p += 1;
        }
        self.precision = Some(p);
        self
    }

    /// Sets the precision of this histogram directly.

Review comment (suggestion):
I'd revert the order of this sentence so you first say that passing 0 results in buckets with doubling being used for the size, and then you can comment that this matches the behavior used in the legacy implementation.

Code after:
/// 3. `precision`: max error of 25%
///
/// This uses 237 64-bit buckets.
#[derive(Default, Debug, Copy, Clone)]
pub struct LogHistogramBuilder {
    max_value: Option<Duration>,
    min_value: Option<Duration>,
    precision: Option<u32>,
}

impl From<LogHistogramBuilder> for LogHistogram {
    fn from(value: LogHistogramBuilder) -> Self {
        value.build()
    }
}

impl LogHistogramBuilder {
    /// Set the precision for this histogram
    ///
    /// This function determines the smallest value of `p` that would satisfy the requested precision
    /// such that `2^-p` is less than `precision`. To set `p` directly, use
    /// [`LogHistogramBuilder::precision_exact`].
    ///
    /// Precision controls the size of the "bucket groups" (consecutive buckets with identical
    /// ranges). When `p` is 0, each bucket will be twice the size of the previous bucket. To match
    /// the behavior of the legacy log histogram implementation, use `builder.precision_exact(0)`.
    ///
    /// The default value is 25% (2^-2)
    ///
    /// The highest supported precision is `0.0977%` `(2^-10)`. Provided values
    /// less than this will be truncated.
    ///
    /// # Panics
    /// - `max_error` < 0
    /// - `max_error` > 1
    pub fn max_error(mut self, max_error: f64) -> Self {
        assert!(max_error > 0.0, "max_error must be greater than 0");
        assert!(max_error < 1.0, "max_error must be less than 1");
        let mut p = 2;
        while 2_f64.powf(-1.0 * p as f64) > max_error && p <= MAX_PRECISION {
            p += 1;
        }
        self.precision = Some(p);
        self
    }

    /// Sets the precision of this histogram directly.
    ///
    /// The precision (meaning: the ratio `n/bucket_range(n)` for some given `n`) will be `2^-p`.
    ///
    /// Precision controls the number consecutive buckets with identically sized ranges.