use indexmap::IndexMap;
use left_right::Absorb;
use std::hash::Hash;
use crate::{ChiralMapConfig, chiral_map::Operation};
#[cfg(feature = "metrics")]
use crate::metrics::Metrics;
#[derive(Clone)]
pub(crate) struct SingleMap<K, V> {
map: IndexMap<K, V>,
#[cfg(feature = "metrics")]
metrics: Metrics,
}
impl<K, V> Absorb<Operation<K, V>> for SingleMap<K, V>
where
K: Hash + Eq + Clone,
V: Clone,
{
fn absorb_first(&mut self, operation: &mut Operation<K, V>, _other: &Self) {
self.step(operation.clone());
}
fn absorb_second(&mut self, operation: Operation<K, V>, _other: &Self) {
self.step(operation);
}
fn sync_with(&mut self, first: &Self) {
first.map.iter().for_each(|(k, v)| {
self.map.insert(k.clone(), v.clone());
});
}
}
impl<K, V> SingleMap<K, V>
where
K: Hash + Eq + Clone,
V: Clone,
{
pub(crate) fn step(&mut self, operation: Operation<K, V>) {
match operation {
Operation::Insert(k, v) => {
self.map.insert(k, v);
#[cfg(feature = "metrics")]
self.metrics.inserted(&self.map);
}
Operation::Delete(k) => {
self.map.swap_remove(&k);
#[cfg(feature = "metrics")]
self.metrics.removed(&self.map);
}
}
}
}
impl<K, V> SingleMap<K, V>
where
K: Hash + Eq + Clone,
V: Clone,
{
pub(crate) fn new(config: &ChiralMapConfig) -> Self {
let map = IndexMap::<K, V>::with_capacity(config.initial_capacity);
Self {
map,
#[cfg(feature = "metrics")]
metrics: Metrics::new(config),
}
}
pub(crate) fn get(&self, k: &K) -> Option<&V> {
self.map.get(k)
}
}