LCOV - code coverage report
Current view: top level - pageserver/pagebench/src/util - request_stats.rs (source / functions) Coverage Total Hit
Test: 53437f7e869ac68c86c7d3e4c20964c0156f158c.info Lines: 0.0 % 54 0
Test Date: 2024-09-20 16:14:12 Functions: 0.0 % 10 0

            Line data    Source code
       1              : use std::time::Duration;
       2              : 
       3              : use anyhow::Context;
       4              : 
       5              : pub(crate) struct Stats {
       6              :     latency_histo: hdrhistogram::Histogram<u64>,
       7              : }
       8              : 
       9              : impl Stats {
      10            0 :     pub(crate) fn new() -> Self {
      11            0 :         Self {
      12            0 :             // Initialize with fixed bounds so that we panic at runtime instead of resizing the histogram,
      13            0 :             // which would skew the benchmark results.
      14            0 :             latency_histo: hdrhistogram::Histogram::new_with_bounds(1, 1_000_000_000, 3).unwrap(),
      15            0 :         }
      16            0 :     }
      17            0 :     pub(crate) fn observe(&mut self, latency: Duration) -> anyhow::Result<()> {
      18            0 :         let micros: u64 = latency
      19            0 :             .as_micros()
      20            0 :             .try_into()
      21            0 :             .context("latency greater than u64")?;
      22            0 :         self.latency_histo
      23            0 :             .record(micros)
      24            0 :             .context("add to histogram")?;
      25            0 :         Ok(())
      26            0 :     }
      27            0 :     pub(crate) fn output(&self) -> Output {
      28            0 :         let latency_percentiles = std::array::from_fn(|idx| {
      29            0 :             let micros = self
      30            0 :                 .latency_histo
      31            0 :                 .value_at_percentile(LATENCY_PERCENTILES[idx]);
      32            0 :             Duration::from_micros(micros)
      33            0 :         });
      34            0 :         Output {
      35            0 :             request_count: self.latency_histo.len(),
      36            0 :             latency_mean: Duration::from_micros(self.latency_histo.mean() as u64),
      37            0 :             latency_percentiles: LatencyPercentiles {
      38            0 :                 latency_percentiles,
      39            0 :             },
      40            0 :         }
      41            0 :     }
      42            0 :     pub(crate) fn add(&mut self, other: &Self) {
      43            0 :         let Self {
      44            0 :             ref mut latency_histo,
      45            0 :         } = self;
      46            0 :         latency_histo.add(&other.latency_histo).unwrap();
      47            0 :     }
      48              : }
      49              : 
      50              : impl Default for Stats {
      51            0 :     fn default() -> Self {
      52            0 :         Self::new()
      53            0 :     }
      54              : }
      55              : 
      56              : const LATENCY_PERCENTILES: [f64; 4] = [95.0, 99.00, 99.90, 99.99];
      57              : 
      58              : struct LatencyPercentiles {
      59              :     latency_percentiles: [Duration; 4],
      60              : }
      61              : 
      62              : impl serde::Serialize for LatencyPercentiles {
      63            0 :     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
      64            0 :     where
      65            0 :         S: serde::Serializer,
      66            0 :     {
      67              :         use serde::ser::SerializeMap;
      68            0 :         let mut ser = serializer.serialize_map(Some(LATENCY_PERCENTILES.len()))?;
      69            0 :         for (p, v) in LATENCY_PERCENTILES.iter().zip(&self.latency_percentiles) {
      70            0 :             ser.serialize_entry(
      71            0 :                 &format!("p{p}"),
      72            0 :                 &format!("{}", humantime::format_duration(*v)),
      73            0 :             )?;
      74              :         }
      75            0 :         ser.end()
      76            0 :     }
      77              : }
      78              : 
      79            0 : #[derive(serde::Serialize)]
      80              : pub(crate) struct Output {
      81              :     request_count: u64,
      82              :     #[serde(with = "humantime_serde")]
      83              :     latency_mean: Duration,
      84              :     latency_percentiles: LatencyPercentiles,
      85              : }
        

Generated by: LCOV version 2.1-beta