use std::collections::HashMap;
use crate::server::current_epoch;
#[derive(Debug, Clone)]
pub struct ReliableWindow {
window: (u32, u32),
size: u32,
queue: HashMap<u32, u64>,
}
impl ReliableWindow {
pub fn new() -> Self {
Self {
window: (0, 2048),
size: 2048,
queue: HashMap::new(),
}
}
pub fn insert(&mut self, index: u32) -> bool {
if index < self.window.0 || index > self.window.1 || self.queue.contains_key(&index) {
return false;
}
self.queue.insert(index, current_epoch());
if index == self.window.0 {
self.adjust();
}
return true;
}
pub fn adjust(&mut self) {
while self.queue.contains_key(&self.window.0) {
self.queue.remove(&self.window.0);
self.window.0 = self.window.0.wrapping_add(1);
self.window.1 = self.window.1.wrapping_add(1);
}
let curr_size = self.window.1.wrapping_sub(self.window.0);
if curr_size < self.size {
self.window.1 = self.window.0.wrapping_add(self.size);
} else if curr_size > self.size {
self.window.0 = self.window.1.wrapping_sub(self.size);
}
}
pub fn missing(&self) -> Vec<u32> {
let mut missing = Vec::new();
for i in self.window.0..self.window.1 {
if !self.queue.contains_key(&i) {
missing.push(i);
}
}
missing
}
pub fn range(&self) -> (u32, u32) {
self.window
}
pub fn clear_outdated(&mut self) {
self.queue
.retain(|k, _| *k >= self.window.0 && *k <= self.window.1);
}
}
pub struct Window {
pub rtt: u32,
}