Skip to main content

cbtop/latency_distribution/
classification.rs

1//! Tail severity and distribution shape classification.
2
3/// Tail latency severity classification
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum TailSeverity {
6    /// Excellent: P99/P50 < 2
7    Excellent,
8    /// Good: P99/P50 < 3
9    Good,
10    /// Warning: P99/P50 < 5
11    Warning,
12    /// Critical: P99/P50 >= 5
13    Critical,
14}
15
16impl TailSeverity {
17    /// Classify based on tail ratio
18    pub fn from_ratio(ratio: f64) -> Self {
19        if ratio < 2.0 {
20            Self::Excellent
21        } else if ratio < 3.0 {
22            Self::Good
23        } else if ratio < 5.0 {
24            Self::Warning
25        } else {
26            Self::Critical
27        }
28    }
29
30    /// Get human-readable name
31    pub fn name(&self) -> &'static str {
32        match self {
33            Self::Excellent => "excellent",
34            Self::Good => "good",
35            Self::Warning => "warning",
36            Self::Critical => "critical",
37        }
38    }
39}
40
41/// Distribution shape classification
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub enum DistributionShape {
44    /// Unimodal (single peak)
45    Unimodal,
46    /// Bimodal (two peaks) - often indicates cache hit/miss
47    Bimodal,
48    /// Multimodal (multiple peaks)
49    Multimodal,
50    /// Uniform (flat)
51    Uniform,
52}
53
54impl DistributionShape {
55    /// Classify based on bimodality coefficient and entropy
56    pub fn classify(bimodality_coeff: f64, entropy: f64) -> Self {
57        if entropy > 0.95 {
58            Self::Uniform
59        } else if bimodality_coeff > 0.555 {
60            Self::Bimodal
61        } else if bimodality_coeff > 0.7 {
62            Self::Multimodal
63        } else {
64            Self::Unimodal
65        }
66    }
67
68    /// Get name
69    pub fn name(&self) -> &'static str {
70        match self {
71            Self::Unimodal => "unimodal",
72            Self::Bimodal => "bimodal",
73            Self::Multimodal => "multimodal",
74            Self::Uniform => "uniform",
75        }
76    }
77}