use crate::{MBiaz, PacketLoss, Spike, ZigZag};
#[derive(Debug)]
pub struct ZBS {
mbiaz: MBiaz,
spike: Spike,
zigzag: ZigZag,
t_avg: f64,
t_min: f64,
rott_min: f64,
}
impl Default for ZBS {
fn default() -> Self {
Self {
mbiaz: MBiaz::default(),
spike: Spike::default(),
zigzag: ZigZag::default(),
t_avg: 0.0,
t_min: std::f64::MAX,
rott_min: std::f64::MAX,
}
}
}
impl ZBS {
pub fn new(mbiaz: MBiaz, spike: Spike, zigzag: ZigZag) -> Self {
Self {
mbiaz,
spike,
zigzag,
t_avg: 0.0,
t_min: std::f64::MAX,
rott_min: std::f64::MAX,
}
}
pub fn classify(
&mut self,
rott: f64,
interarrival_time: f64,
num_lost_packets: u32,
) -> PacketLoss {
assert!(rott >= 0.0);
assert!(interarrival_time >= 0.0);
assert!(num_lost_packets > 0);
if interarrival_time < self.t_min {
self.t_min = interarrival_time;
}
if rott < self.rott_min {
self.rott_min = rott;
}
self.t_avg = 0.875 * self.t_avg
+ 0.125 * interarrival_time * interarrival_time / num_lost_packets as f64;
let t_narr = self.t_avg / self.t_min;
if rott < self.rott_min + 0.05 * self.t_min {
self.spike.classify(rott)
} else {
if t_narr < 0.875 {
self.zigzag.classify(rott, num_lost_packets)
} else if t_narr < 1.5 {
self.mbiaz.classify(interarrival_time, num_lost_packets)
} else if t_narr < 2.0 {
self.zigzag.classify(rott, num_lost_packets)
} else {
self.spike.classify(rott)
}
}
}
}