use crate::PacketLoss;
#[derive(Debug)]
pub struct ZigZag {
rott_mean: f64,
rott_dev: f64,
alpha: f64,
}
impl Default for ZigZag {
fn default() -> Self {
Self {
rott_mean: 0.0,
rott_dev: 0.0,
alpha: 1.0 / 32.0,
}
}
}
impl ZigZag {
pub fn new(alpha: f64) -> Self {
assert!(0.0 <= alpha && alpha <= 1.0);
Self {
rott_mean: 0.0,
rott_dev: 0.0,
alpha,
}
}
pub fn classify(&mut self, rott: f64, num_lost_packets: u32) -> PacketLoss {
assert!(rott >= 0.0);
assert!(num_lost_packets > 0);
self.rott_mean = (1.0 - self.alpha) * self.rott_mean + self.alpha * rott;
self.rott_dev = (1.0 - 2.0 * self.alpha) + 2.0 * self.alpha * (rott - self.rott_mean).abs();
match num_lost_packets {
1 => {
if rott < self.rott_mean - self.rott_dev {
PacketLoss::Wireless
} else {
PacketLoss::Congestion
}
}
2 => {
if rott < self.rott_mean - self.rott_dev / 2.0 {
PacketLoss::Wireless
} else {
PacketLoss::Congestion
}
}
3 => {
if rott < self.rott_mean {
PacketLoss::Wireless
} else {
PacketLoss::Congestion
}
}
_ => {
if rott < self.rott_mean + self.rott_dev / 2.0 {
PacketLoss::Wireless
} else {
PacketLoss::Congestion
}
}
}
}
}