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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#[allow(unused_imports)]
use crate::Llrb;
#[derive(Clone)]
pub struct Depth {
samples: usize,
min: usize,
max: usize,
total: usize,
depths: [u64; 256],
}
impl Depth {
pub(crate) fn new() -> Depth {
Default::default()
}
pub(crate) fn sample(&mut self, depth: usize) {
self.samples += 1;
self.total += depth;
if self.min == 0 || depth < self.min {
self.min = depth
}
if self.max == 0 || depth > self.max {
self.max = depth
}
self.depths[depth] += 1;
}
pub fn samples(&self) -> usize {
self.samples
}
pub fn min(&self) -> usize {
self.min
}
pub fn max(&self) -> usize {
self.max
}
pub fn mean(&self) -> usize {
self.total / self.samples
}
pub fn percentiles(&self) -> Vec<(u8, usize)> {
let mut percentiles: Vec<(u8, usize)> = vec![];
let (mut acc, mut prev_perc) = (0_u64, 90_u8);
let iter = self.depths.iter().enumerate().filter(|(_, &item)| item > 0);
for (depth, samples) in iter {
acc += *samples;
let perc = ((acc as f64 / self.samples as f64) * 100_f64) as u8;
if perc >= prev_perc {
percentiles.push((perc, depth));
prev_perc = perc;
}
}
percentiles
}
pub fn pretty_print(&self, prefix: &str) {
let mean = self.mean();
println!(
"{}depth (min, max, avg): {:?}",
prefix,
(self.min, mean, self.max)
);
for (depth, n) in self.percentiles().into_iter() {
if n > 0 {
println!("{} {} percentile = {}", prefix, depth, n);
}
}
}
pub fn json(&self) -> String {
let ps: Vec<String> = self
.percentiles()
.into_iter()
.map(|(d, n)| format!("{}: {}", d, n))
.collect();
let strs = [
format!("min: {}", self.min),
format!("mean: {}", self.mean()),
format!("max: {}", self.max),
format!("percentiles: {}", ps.join(", ")),
];
("{ ".to_string() + strs.join(", ").as_str() + " }").to_string()
}
}
impl Default for Depth {
fn default() -> Self {
Depth {
samples: 0,
min: 0,
max: 0,
total: 0,
depths: [0; 256],
}
}
}