persy 1.5.2

Transactional Persistence Engine
Documentation
use crate::{
    address::record_scanner::{SegmentRawIter, SegmentSnapshotRawIter, TxSegmentRawIter},
    persy::PersyImpl,
    PersyId, Transaction,
};
use std::sync::Arc;

/// Iterator implementation used to scan a segment
///
/// # Example
///
/// ```rust
/// # use persy::{Persy,Config};
/// # use persy::{OpenOptions};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_segment("seg")?;
/// let data = vec![1;20];
/// let id = tx.insert("seg", &data)?;
/// let prepared = tx.prepare()?;
/// prepared.commit()?;
/// let mut count = 0;
/// for (id,content) in persy.scan("seg")? {
///     println!("record size:{}",content.len());
///     count+=1;
/// }
/// assert_eq!(count,1);
/// # Ok(())
/// # }
/// ```
pub struct SegmentIter {
    iter_impl: SegmentRawIter,
    persy_impl: Arc<PersyImpl>,
}

impl SegmentIter {
    pub(crate) fn new(iter_impl: SegmentRawIter, persy_impl: Arc<PersyImpl>) -> SegmentIter {
        SegmentIter { iter_impl, persy_impl }
    }
}

impl Iterator for SegmentIter {
    type Item = (PersyId, Vec<u8>);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter_impl.next(&self.persy_impl)
    }
}

struct RawIterDrop {
    iter_impl: TxSegmentRawIter,
}

/// Iterator implementation to scan a segment considering in transaction changes.
///
/// # Example
///
/// ```rust
/// # use persy::{OpenOptions};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_segment("seg")?;
/// let data = vec![1;20];
/// let id = tx.insert("seg", &data)?;
/// let mut count = 0;
/// for (id,content) in tx.scan("seg")? {
///     println!("record size:{}",content.len());
///     count+=1;
/// }
/// assert_eq!(count,1);
/// # Ok(())
/// # }
/// ```
pub struct TxSegmentIter<'a> {
    iter_impl: RawIterDrop,
    tx: &'a mut Transaction,
}

impl<'a> TxSegmentIter<'a> {
    pub(crate) fn new(iter_impl: TxSegmentRawIter, tx: &'a mut Transaction) -> TxSegmentIter<'a> {
        TxSegmentIter {
            iter_impl: RawIterDrop { 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<(PersyId, Vec<u8>, &mut Transaction)> {
        if let Some((id, rec, _)) = self
            .iter_impl
            .iter_impl
            .next(&self.tx.persy_impl, self.tx.tx.as_mut().unwrap())
        {
            Some((id, rec, self.tx))
        } else {
            None
        }
    }

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

impl<'a> Iterator for TxSegmentIter<'a> {
    type Item = (PersyId, Vec<u8>);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter_impl
            .iter_impl
            .next(&self.tx.persy_impl, self.tx.tx.as_mut().unwrap())
            .map(|(id, content, _)| (id, content))
    }
}

/// Iterator implementation to scan a segment at the current snapshot state.
///
/// # Example
/// ```rust
/// # use persy::{OpenOptions};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # let persy = OpenOptions::new().memory()?;
/// let mut tx = persy.begin()?;
/// # tx.create_segment("seg")?;
/// let data = vec![1;20];
/// let id = tx.insert("seg", &data)?;
/// tx.prepare()?.commit()?;
/// let snapshot = persy.snapshot()?;
/// let mut count = 0;
/// for (id,content) in snapshot.scan("seg")? {
///     println!("record size:{}",content.len());
///     count+=1;
/// }
/// assert_eq!(count,1);
/// # Ok(())
/// # }
/// ```
pub struct SnapshotSegmentIter {
    iter_impl: SegmentSnapshotRawIter,
    persy_impl: Arc<PersyImpl>,
}

impl SnapshotSegmentIter {
    pub(crate) fn new(iter_impl: SegmentSnapshotRawIter, persy_impl: Arc<PersyImpl>) -> SnapshotSegmentIter {
        SnapshotSegmentIter { iter_impl, persy_impl }
    }
}

impl Iterator for SnapshotSegmentIter {
    type Item = (PersyId, Vec<u8>);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter_impl.next(&self.persy_impl)
    }
}