use super::bitmap::SlidingBitmap;
use super::{Seq, Stamp, WINDOW_SIZE};
#[derive(Debug)]
pub(super) struct PeerState {
max_seq: Seq,
stamp_at_max: Stamp,
max_stamp_seen: Stamp,
bitmap: SlidingBitmap,
}
impl PeerState {
pub(super) fn new(first_seq: Seq, first_stamp: Stamp) -> Self {
PeerState {
max_seq: first_seq,
stamp_at_max: first_stamp,
max_stamp_seen: first_stamp,
bitmap: SlidingBitmap::new(),
}
}
pub(super) fn stamp_at_max(&self) -> Stamp {
self.stamp_at_max
}
pub(super) fn accept(&mut self, seq: Seq, stamp: Stamp) -> bool {
if seq > self.max_seq {
if stamp < self.max_stamp_seen {
return false;
}
let delta = seq - self.max_seq;
self.bitmap.advance(delta);
self.max_seq = seq;
self.stamp_at_max = stamp;
self.max_stamp_seen = self.max_stamp_seen.max(stamp);
true
} else {
if stamp > self.stamp_at_max {
self.reset(seq, stamp);
return true;
}
let behind = self.max_seq - seq;
if behind >= WINDOW_SIZE {
return false;
}
if self.bitmap.is_marked(behind) {
return false;
}
self.bitmap.mark(behind);
true
}
}
fn reset(&mut self, new_seq: Seq, new_stamp: Stamp) {
self.max_seq = new_seq;
self.stamp_at_max = new_stamp;
self.max_stamp_seen = self.max_stamp_seen.max(new_stamp);
self.bitmap = SlidingBitmap::new();
}
}