alloc_test/alloc/
compare.rs1use derive_builder::Builder;
2use thiserror::Error;
3
4use super::measure::MemoryStats;
5use crate::threshold::{Threshold, ThresholdError, ThresholdFor};
6
7#[derive(Debug, Builder)]
9pub struct AllocThresholds {
10 #[builder(default)]
11 pub current: Threshold<usize>,
12 #[builder(default)]
13 pub peak: Threshold<usize>,
14 #[builder(default)]
15 pub total_size: Threshold<usize>,
16 #[builder(default)]
17 pub total_num: Threshold<usize>,
18 #[builder(default)]
19 pub reallocs: Threshold<usize>,
20}
21
22#[derive(Debug, Error)]
23#[error("Allocation parameter `{param}`: {error}")]
24pub struct AllocThresholdsError {
25 error: ThresholdError<usize>,
26 param: &'static str,
27}
28
29macro_rules! check {
30 ($f:ident, $l:expr, $v:expr, $r:expr) => {
31 $l.$f
32 .check(&$v.$f, &$r.$f)
33 .map_err(|e| AllocThresholdsError {
34 error: e,
35 param: stringify!($f),
36 })
37 };
38}
39
40impl ThresholdFor<MemoryStats> for AllocThresholds {
41 type Error = AllocThresholdsError;
42
43 fn check_threshold(
44 &self,
45 value: &MemoryStats,
46 ref_value: &MemoryStats,
47 ) -> Result<(), Self::Error> {
48 self.check(value, ref_value)
49 }
50}
51
52impl AllocThresholds {
53 pub fn check(
54 &self,
55 value: &MemoryStats,
56 ref_value: &MemoryStats,
57 ) -> Result<(), AllocThresholdsError> {
58 check!(current, self, value, ref_value)?;
59 check!(peak, self, value, ref_value)?;
60 check!(total_size, self, value, ref_value)?;
61 check!(total_num, self, value, ref_value)?;
62 check!(reallocs, self, value, ref_value)?;
63 Ok(())
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn limits() {
73 let rs = MemoryStats {
74 current: 100,
75 peak: 1000,
76 total_size: 2000,
77 total_num: 100,
78 reallocs: 0,
79 };
80 let vs = MemoryStats {
81 current: 110,
82 peak: 1100,
83 total_size: 2200,
84 total_num: 110,
85 reallocs: 1,
86 };
87
88 let ls = AllocThresholdsBuilder::default().build().unwrap();
89 assert!(ls.check_threshold(&rs, &rs).is_ok());
90 assert!(ls.check_threshold(&vs, &rs).is_ok());
91
92 let ls = AllocThresholdsBuilder::default()
93 .current(Threshold::Cap(1))
94 .build()
95 .unwrap();
96 let r = ls.check(&vs, &rs);
97 assert!(r.unwrap_err().param == "current");
98
99 let ls = AllocThresholdsBuilder::default()
100 .reallocs(Threshold::Cap(0))
101 .build()
102 .unwrap();
103 let r = ls.check(&vs, &rs);
104 assert!(r.unwrap_err().param == "reallocs");
105 }
106}