use std::collections::{HashSet, VecDeque};
pub const DEFAULT_WINDOW_SIZE: usize = 8192;
pub struct InboundDedup {
seen: HashSet<u64>,
order: VecDeque<u64>,
capacity: usize,
}
impl Default for InboundDedup {
fn default() -> Self {
Self::new()
}
}
impl InboundDedup {
pub fn new() -> Self {
Self::with_capacity(DEFAULT_WINDOW_SIZE)
}
pub fn with_capacity(capacity: usize) -> Self {
let capacity = capacity.max(1);
Self {
seen: HashSet::with_capacity(capacity),
order: VecDeque::with_capacity(capacity),
capacity,
}
}
pub fn contains(&self, hash: u64) -> bool {
self.seen.contains(&hash)
}
pub fn record(&mut self, hash: u64) -> bool {
if !self.seen.insert(hash) {
return true;
}
self.order.push_back(hash);
if self.order.len() > self.capacity {
if let Some(evicted) = self.order.pop_front() {
self.seen.remove(&evicted);
}
}
false
}
pub fn clear(&mut self) {
self.seen.clear();
self.order.clear();
}
pub fn len(&self) -> usize {
self.order.len()
}
pub fn is_empty(&self) -> bool {
self.order.is_empty()
}
pub fn capacity(&self) -> usize {
self.capacity
}
}