use std::time::Duration;
use crate::container::Timestamp;
#[derive(Default)]
pub struct Jitter {
last_timestamp: Option<Timestamp>,
min_duration: Option<Duration>,
max_reorder: Duration,
reported: Option<Duration>,
}
impl Jitter {
pub fn new() -> Self {
Self::default()
}
pub fn observe(&mut self, ts: Timestamp) -> Option<Duration> {
if let Some(last) = self.last_timestamp.replace(ts)
&& let Ok(duration) = ts.checked_sub(last)
&& !duration.is_zero()
{
let duration = Duration::from(duration);
self.min_duration = Some(match self.min_duration {
Some(min) => min.min(duration),
None => duration,
});
}
self.report()
}
pub fn observe_reorder(&mut self, reorder: Timestamp) -> Option<Duration> {
self.max_reorder = self.max_reorder.max(Duration::from(reorder));
self.report()
}
pub fn current(&self) -> Option<Duration> {
let jitter = self.combined();
(!jitter.is_zero()).then_some(jitter)
}
fn combined(&self) -> Duration {
self.min_duration.unwrap_or(Duration::ZERO).max(self.max_reorder)
}
fn report(&mut self) -> Option<Duration> {
let jitter = self.combined();
if jitter.is_zero() || self.reported == Some(jitter) {
return None;
}
self.reported = Some(jitter);
Some(jitter)
}
}