persy 1.8.0

Transactional Persistence Engine
Documentation
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)
    }
}