persy 1.5.2

Transactional Persistence Engine
Documentation
use crate::{
    index::{
        config::{IndexType, IndexTypeUnwrap},
        raw_iter::IndexRawIter,
        raw_iter_tx::TxIndexRawIter,
    },
    persy::PersyImpl,
    Transaction, ValueIter,
};
use std::sync::Arc;

/// Index Iterator implementation for iterating on a range of keys
///
/// Example
/// ```rust
/// # use persy::{OpenOptions,ValueMode, IndexIter};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// # let mut tx = persy.begin()?;
/// # tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
/// # tx.put::<u8,u8>("my_new_index",10,10)?;
/// # let prepared = tx.prepare()?;
/// # prepared.commit()?;
/// let iter:IndexIter<u8,u8> = persy.range("my_new_index",10..12)?;
/// for (k,values) in iter  {
///     for value in values {
///         //...
///     }
/// }
/// # Ok(())
/// # }
/// ```
pub struct IndexIter<K: IndexType, V: IndexType> {
    iter_impl: IndexRawIter<K::Wrapper, V::Wrapper>,
    persy_impl: Arc<PersyImpl>,
}

impl<K: IndexType, V: IndexType> IndexIter<K, V> {
    pub(crate) fn new(iter_impl: IndexRawIter<K::Wrapper, V::Wrapper>, persy_impl: Arc<PersyImpl>) -> IndexIter<K, V> {
        IndexIter { iter_impl, persy_impl }
    }
}

impl<K, V> Iterator for IndexIter<K, V>
where
    K: IndexType,
    V: IndexType,
{
    type Item = (K, ValueIter<V>);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter_impl
            .next(&self.persy_impl)
            .map(|(k, v)| (k.unwrap(), ValueIter::from(v)))
    }
}
impl<K, V> DoubleEndedIterator for IndexIter<K, V>
where
    K: IndexType,
    V: IndexType,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iter_impl
            .next_back(&self.persy_impl)
            .map(|(k, v)| (k.unwrap(), ValueIter::from(v)))
    }
}

/// Index Iterator implementation for iterating on a range of keys
/// considering changes in transaction
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions, ValueMode, TxIndexIter};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_index::<u8,u8>("my_new_index", ValueMode::Cluster)?;
/// tx.put::<u8,u8>("my_new_index",10,10)?;
/// {
///     let iter:TxIndexIter<u8,u8> = tx.range("my_new_index",10..12)?;
///     for (k,values) in iter  {
///         for value in values {
///             //...
///         }
///     }
/// }
/// tx.prepare()?.commit()?;
/// # Ok(())
/// # }
/// ```
pub struct TxIndexIter<'a, K: IndexType, V: IndexType> {
    iter_impl: TxIndexRawIter<K::Wrapper, V::Wrapper>,
    tx: &'a mut Transaction,
}

impl<'a, K: IndexType, V: IndexType> TxIndexIter<'a, K, V> {
    pub(crate) fn new(
        iter_impl: TxIndexRawIter<K::Wrapper, V::Wrapper>,
        tx: &'a mut Transaction,
    ) -> TxIndexIter<'a, K, V> {
        TxIndexIter { iter_impl, tx }
    }

    /// get the next element in the iterator giving the access on the transaction owned by the
    /// iterator
    pub fn next_tx(&mut self) -> Option<(K, ValueIter<V>, &mut Transaction)> {
        if let Some((k, v)) = self.iter_impl.next(&self.tx.persy_impl, self.tx.tx.as_mut().unwrap()) {
            Some((k.unwrap(), ValueIter::from(v), self.tx))
        } else {
            None
        }
    }

    /// Direct access to the transaction owned by the iterator
    pub fn tx(&mut self) -> &mut Transaction {
        self.tx
    }
}

impl<'a, K, V> Iterator for TxIndexIter<'a, K, V>
where
    K: IndexType,
    V: IndexType,
{
    type Item = (K, ValueIter<V>);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter_impl
            .next(&self.tx.persy_impl, self.tx.tx.as_mut().unwrap())
            .map(|(k, v)| (k.unwrap(), ValueIter::from(v)))
    }
}

impl<'a, K, V> DoubleEndedIterator for TxIndexIter<'a, K, V>
where
    K: IndexType,
    V: IndexType,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iter_impl
            .next_back(&self.tx.persy_impl, self.tx.tx.as_mut().unwrap())
            .map(|(k, v)| (k.unwrap(), ValueIter::from(v)))
    }
}