Skip to main content

vantage_api_pool/stats/
average.rs

1use rust_decimal::prelude::*;
2use std::time::Duration;
3
4#[derive(Debug, Clone, Default, Copy)]
5pub struct Average {
6    total: Decimal,
7    count: Decimal,
8}
9
10impl Average {
11    pub fn new() -> Self {
12        Self {
13            total: Decimal::ZERO,
14            count: Decimal::ZERO,
15        }
16    }
17
18    pub fn add_sample(&mut self, value: Decimal) {
19        self.total += value;
20        self.count += Decimal::ONE;
21    }
22
23    pub fn get_value(&self) -> Decimal {
24        if self.count > Decimal::ZERO {
25            self.total / self.count
26        } else {
27            Decimal::ZERO
28        }
29    }
30
31    pub fn reset(&mut self) {
32        self.total = Decimal::ZERO;
33        self.count = Decimal::ZERO;
34    }
35
36    pub fn from_duration(duration: Duration) -> Self {
37        let mut avg = Self::new();
38        avg.add_sample(Decimal::from(duration.as_millis() as u64));
39        avg
40    }
41}
42
43impl std::ops::Add for Average {
44    type Output = Average;
45
46    fn add(self, other: Average) -> Average {
47        Average {
48            total: self.total + other.total,
49            count: self.count + other.count,
50        }
51    }
52}
53
54impl std::ops::Sub for Average {
55    type Output = Average;
56
57    fn sub(self, other: Average) -> Average {
58        Average {
59            total: self.total.saturating_sub(other.total),
60            count: self.count.saturating_sub(other.count),
61        }
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_average_operations() {
71        // First second: 10 requests
72        let mut first_second = Average::new();
73        first_second.add_sample(dec!(10));
74        assert_eq!(first_second.get_value(), dec!(10));
75
76        // Second second: 9 requests
77        let mut second_second = Average::new();
78        second_second.add_sample(dec!(9));
79        assert_eq!(second_second.get_value(), dec!(9));
80
81        // Average RPS after 2 seconds: (10+9)/2 = 9.5
82        let two_seconds = first_second + second_second;
83        assert_eq!(two_seconds.get_value(), dec!(9.5));
84
85        // Third second: 8 requests
86        let mut third_second = Average::new();
87        third_second.add_sample(dec!(8));
88        assert_eq!(third_second.get_value(), dec!(8));
89
90        // Average RPS after 3 seconds: (10+9+8)/3 = 9
91        let three_seconds = two_seconds + third_second;
92        assert_eq!(three_seconds.get_value(), dec!(9));
93
94        // Subtract first second: (9+8)/2 = 8.5
95        let without_first = three_seconds - first_second;
96        assert_eq!(without_first.get_value(), dec!(8.5));
97    }
98}