use std::collections::BTreeMap;
enum EntryState<V> {
Deleted,
Occupied(V),
}
pub(crate) struct TempMap<'a, K, V: 'a> {
base_index: &'a mut BTreeMap<K, V>,
new_index: BTreeMap<K, EntryState<V>>,
}
impl<'a, K, V> TempMap<'a, K, V>
where
K: Ord,
V: 'a + Copy,
{
pub(crate) fn new(base_index: &'a mut BTreeMap<K, V>) -> Self {
Self {
base_index,
new_index: BTreeMap::<K, EntryState<V>>::new(),
}
}
pub(crate) fn get(&self, key: &K) -> Option<V> {
if let Some(state) = self.new_index.get(key) {
match state {
EntryState::Occupied(val) => Some(*val),
EntryState::Deleted => None,
}
} else {
self.base_index.get(key).copied()
}
}
pub(crate) fn contains_key(&self, key: &K) -> bool {
if self.new_index.contains_key(key) {
true
} else {
self.base_index.contains_key(key)
}
}
pub(crate) fn insert(&mut self, key: K, val: V) {
self.new_index.insert(key, EntryState::Occupied(val));
}
pub(crate) fn remove(&mut self, key: K) {
if self.contains_key(&key) {
self.new_index.insert(key, EntryState::Deleted);
}
}
pub(crate) fn commit(self) {
for (key, val) in self.new_index {
match val {
EntryState::Occupied(val) => self.base_index.insert(key, val),
EntryState::Deleted => self.base_index.remove(&key),
};
}
}
}