use std::cmp::Ord;
use std::collections::BTreeSet;
use std::iter::IntoIterator;
#[derive(Debug, Clone)]
pub struct ItemPool<T: Ord + Clone> {
items: BTreeSet<T>,
working_set: BTreeSet<T>,
}
impl<T: Ord + Clone> Default for ItemPool<T> {
fn default() -> Self { Self::new() }
}
impl<T: Ord + Clone> ItemPool<T> {
#[must_use]
pub fn new() -> Self {
Self {
items: BTreeSet::new(),
working_set: BTreeSet::new(),
}
}
pub fn update<I>(&mut self, new_target_ids: I) -> (Vec<T>, Vec<T>)
where
I: IntoIterator<Item = T>,
{
let items = &mut self.items;
let working_set = &mut self.working_set;
working_set.extend(new_target_ids);
let added = working_set.difference(items).cloned().collect::<Vec<_>>();
let removed = items.difference(working_set).cloned().collect::<Vec<_>>();
for item in &removed {
items.remove(item);
}
items.extend(added.iter().cloned());
working_set.clear();
(added, removed)
}
}