const SEQ_NUM_WINDOW_SIZE: u64 = 128;
#[derive(Clone, Copy, Default)]
pub struct SeqNumWindow {
lower: u64,
window: u128,
}
impl SeqNumWindow {
pub fn insert(&mut self, seq: u64) {
if seq < self.lower {
return;
}
if seq > self.upper() {
let diff = seq - self.upper();
self.lower += diff;
self.window = self.window.checked_shl(diff as u32).unwrap_or(0);
}
let mask = 1_u128 << (self.upper() - seq);
self.window |= mask;
}
pub fn contains(&mut self, seq: u64) -> bool {
if seq > self.upper() {
return false;
}
if seq < self.lower {
return true;
}
let mask = 1_u128 << (self.upper() - seq);
self.window & mask != 0
}
fn upper(&self) -> u64 {
self.lower.saturating_add(SEQ_NUM_WINDOW_SIZE) - 1
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn seq_num_window_default() {
let mut win = SeqNumWindow::default();
assert!(!win.contains(0));
assert!(!win.contains(1));
}
#[test]
fn seq_num_window_insert() {
let mut win = SeqNumWindow::default();
win.insert(0);
assert!(win.contains(0));
assert!(!win.contains(1));
win.insert(1);
assert!(win.contains(0));
assert!(win.contains(1));
win.insert(3);
assert!(win.contains(0));
assert!(win.contains(1));
assert!(!win.contains(2));
assert!(win.contains(3));
assert!(!win.contains(200));
}
#[test]
fn seq_num_window_insert_slide() {
let mut win = SeqNumWindow::default();
win.insert(10);
assert!(!win.contains(0));
assert!(win.contains(10));
win.insert(138);
assert!(win.contains(138));
assert!(!win.contains(137));
assert!(win.contains(10));
assert!(win.contains(0));
win.insert(8);
assert!(win.contains(8));
}
#[test]
fn seq_num_window_insert_max() {
let mut win = SeqNumWindow::default();
let max_seq = std::u64::MAX - 1;
win.insert(max_seq);
assert!(win.contains(0));
assert!(win.contains(max_seq));
assert!(!win.contains(max_seq - 1));
assert!(win.contains(max_seq - 128));
}
}