persy 1.5.2

Transactional Persistence Engine
Documentation
use crate::{
    id::IndexId,
    index::{
        config::IndexTypeInternal,
        tree::nodes::{PageIter, PageIterBack, Value},
    },
    persy::PersyImpl,
    snapshots::SnapshotRef,
};
use std::{
    cmp::Ordering,
    ops::{Bound, RangeBounds},
};

pub struct IndexRawIter<K, V> {
    index_id: IndexId,
    read_snapshot: SnapshotRef,
    iter: PageIter<K, V>,
    back: PageIterBack<K, V>,
    range: (Bound<K>, Bound<K>),
}

impl<K: IndexTypeInternal, V> IndexRawIter<K, V>
where
    K: IndexTypeInternal,
    V: IndexTypeInternal,
{
    pub fn new(
        index_id: IndexId,
        read_snapshot: &SnapshotRef,
        iter: PageIter<K, V>,
        back: PageIterBack<K, V>,
        range: (Bound<K>, Bound<K>),
    ) -> IndexRawIter<K, V> {
        IndexRawIter {
            index_id,
            read_snapshot: read_snapshot.clone(),
            iter,
            back,
            range,
        }
    }

    pub fn next(&mut self, persy_impl: &PersyImpl) -> Option<(K, Value<V>)> {
        if let Some(front) = self.iter.iter.peek() {
            if let Some(back) = self.back.iter.peek() {
                if front.key.cmp(&back.key) == Ordering::Greater {
                    return None;
                }
            } else {
                match self.range.end_bound() {
                    Bound::Unbounded => {}
                    Bound::Included(x) => {
                        if x.cmp(&front.key) == Ordering::Less {
                            return None;
                        }
                    }
                    Bound::Excluded(x) => {
                        if front.key.cmp(x) == Ordering::Greater {
                            return None;
                        }
                    }
                }
            }
        }
        if let Some(n) = self.iter.iter.next() {
            if self.iter.iter.peek().is_none() {
                if let Ok(iter) = persy_impl.index_next(&self.index_id, &self.read_snapshot, Bound::Excluded(&n.key)) {
                    self.iter = iter;
                }
            }

            Some((n.key, n.value))
        } else {
            None
        }
    }

    pub fn next_back(&mut self, persy_impl: &PersyImpl) -> Option<(K, Value<V>)> {
        if let Some(back) = self.back.iter.peek() {
            if let Some(front) = self.iter.iter.peek() {
                if back.key.cmp(&front.key) == Ordering::Less {
                    return None;
                }
            } else {
                match self.range.start_bound() {
                    Bound::Unbounded => {}
                    Bound::Included(x) => {
                        if x.cmp(&back.key) == Ordering::Greater {
                            return None;
                        }
                    }
                    Bound::Excluded(x) => {
                        if back.key.cmp(x) == Ordering::Less {
                            return None;
                        }
                    }
                }
            }
        }
        if let Some(n) = self.back.iter.next() {
            if self.back.iter.peek().is_none() {
                if let Ok(back) = persy_impl.index_back(&self.index_id, &self.read_snapshot, Bound::Excluded(&n.key)) {
                    self.back = back;
                }
            }
            Some((n.key, n.value))
        } else {
            None
        }
    }
}