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
}
}
}