use rand::rngs::StdRng;
use rand::Rng;
#[derive(Debug)]
pub struct Reservoir<T> {
capacity: usize,
count: usize,
items: Vec<T>,
rng: StdRng,
}
impl<T> Reservoir<T> {
pub fn new(capacity: usize, rng: StdRng) -> Self {
Self {
capacity,
count: 0,
items: Vec::with_capacity(capacity),
rng,
}
}
pub fn consider(&mut self, item: T) {
self.count += 1;
if self.items.len() < self.capacity {
self.items.push(item);
} else {
let j = self.rng.random_range(0..self.count);
if j < self.capacity {
self.items[j] = item;
}
}
}
pub fn total_seen(&self) -> usize {
self.count
}
pub fn len(&self) -> usize {
self.items.len()
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
pub fn capacity(&self) -> usize {
self.capacity
}
pub fn into_items(self) -> Vec<T> {
self.items
}
pub fn items(&self) -> &[T] {
&self.items
}
}