use crate::PacketLoss;
#[derive(Debug, Clone, Copy)]
enum State {
Spike,
Normal,
}
#[derive(Debug)]
pub struct Spike {
rott_min: f64,
rott_max: f64,
alpha: f64,
beta: f64,
state: State,
}
impl Default for Spike {
fn default() -> Self {
Self {
rott_min: std::f64::MAX,
rott_max: 0.0,
alpha: 1.0 / 2.0,
beta: 1.0 / 3.0,
state: State::Normal,
}
}
}
impl Spike {
pub fn new(alpha: f64, beta: f64) -> Self {
assert!(alpha >= beta);
Self {
alpha,
beta,
rott_min: std::f64::MAX,
rott_max: 0.0,
state: State::Normal,
}
}
pub fn classify(&mut self, rott: f64) -> PacketLoss {
if rott < self.rott_min {
self.rott_min = rott;
}
if rott > self.rott_max {
self.rott_max = rott;
}
let b_spike_start = self.rott_min + self.alpha * (self.rott_max - self.rott_min);
let b_spike_end = self.rott_min + self.beta * (self.rott_max - self.rott_min);
match self.state {
State::Spike => {
if rott < b_spike_end {
self.state = State::Normal;
return PacketLoss::Wireless;
}
return PacketLoss::Congestion;
}
State::Normal => {
if rott > b_spike_start {
self.state = State::Spike;
return PacketLoss::Congestion;
}
return PacketLoss::Wireless;
}
}
}
}