Skip to main content

hopr_transport_session/balancer/
simple.rs

1use crate::balancer::{BalancerControllerBounds, SurbBalancerController};
2
3/// Controller that uses the simple linear formula `limit * min(current / setpoint, 1.0)` to
4/// compute the control output.
5#[derive(Clone, Debug, Default)]
6pub struct SimpleBalancerController {
7    bounds: BalancerControllerBounds,
8}
9
10impl SurbBalancerController for SimpleBalancerController {
11    fn bounds(&self) -> BalancerControllerBounds {
12        self.bounds
13    }
14
15    fn set_target_and_limit(&mut self, bounds: BalancerControllerBounds) {
16        self.bounds = bounds;
17    }
18
19    fn next_control_output(&mut self, current_buffer_level: u64) -> u64 {
20        let ratio = current_buffer_level as f64 / self.bounds.target() as f64;
21        (self.bounds.output_limit() as f64 * ratio.clamp(0.0, 1.0)).floor() as u64
22    }
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28
29    #[test]
30    fn test_simple_balancer() {
31        let mut controller = SimpleBalancerController::default();
32        controller.set_target_and_limit(BalancerControllerBounds::new(100, 100));
33        assert_eq!(100, controller.bounds.target());
34
35        let outputs: Vec<_> = [10, 100, 101]
36            .iter()
37            .map(|&level| controller.next_control_output(level))
38            .collect();
39        assert_eq!(outputs, [10, 100, 100]);
40        assert_eq!(100, controller.bounds.target());
41    }
42}