use crate::{
error::PIRes,
index::{
config::{IndexOrd, IndexTypeInternal, ValueMode},
tree::{ChangeResults, nodes::Leaf},
},
};
#[derive(Clone, Eq, PartialEq, Debug)]
pub(crate) enum ValueChange<V> {
Add(V),
Remove(Option<V>),
}
pub(crate) struct KeyChanges<K, V> {
pub k: K,
changes: Vec<ValueChange<V>>,
}
impl<K: Clone, V: Clone> Clone for KeyChanges<K, V> {
fn clone(&self) -> Self {
Self {
k: self.k.clone(),
changes: self.changes.clone(),
}
}
}
impl<K: IndexOrd + Clone, V: IndexOrd + Clone> KeyChanges<K, V> {
pub(crate) fn new(k: K, changes: Vec<ValueChange<V>>) -> KeyChanges<K, V> {
KeyChanges { k, changes }
}
}
#[cfg(not(feature = "index_container_static"))]
impl<K: IndexOrd + Clone, V: IndexOrd + Clone> KeyChanges<K, V> {
pub(crate) fn put(&mut self, v: V) {
self.changes.push(ValueChange::Add(v))
}
pub(crate) fn remove(&mut self, v: Option<V>) {
self.changes.push(ValueChange::Remove(v))
}
pub(crate) fn changes(&self) -> Vec<ValueChange<V>> {
self.changes.clone()
}
}
#[cfg(test)]
impl<K: IndexOrd + Clone, V: IndexOrd + Clone> KeyChanges<K, V> {
pub(crate) fn single_add(k: K, v: V) -> KeyChanges<K, V> {
KeyChanges {
k,
changes: vec![ValueChange::Add(v)],
}
}
pub(crate) fn single_delete(k: K, v: Option<V>) -> KeyChanges<K, V> {
KeyChanges {
k,
changes: vec![ValueChange::Remove(v)],
}
}
}
impl<K: IndexTypeInternal, V: IndexOrd + Clone> KeyChanges<K, V> {
pub(crate) fn apply(&self, leaf: &mut Leaf<K, V>, value_mode: ValueMode, index: &str) -> PIRes<ChangeResults> {
let mut cr = ChangeResults {
add: None,
remove: None,
};
for vc in &self.changes {
match vc {
ValueChange::Add(v) => {
leaf.add(&self.k, v, value_mode.clone(), index)?;
cr.add = if let Some(add) = cr.add { Some(add + 1) } else { Some(1) };
}
ValueChange::Remove(r) => {
if leaf.remove(&self.k, r) {
cr.remove = if let Some(remove) = cr.remove {
Some(remove + 1)
} else {
Some(1)
};
}
}
};
}
Ok(cr)
}
}