use std::marker::PhantomData;
use std::ops::Bound;
#[cfg(feature = "loom")]
use loom::sync::atomic::Ordering;
#[cfg(not(feature = "loom"))]
use std::sync::atomic::Ordering;
use super::SkipList;
use super::node::SkipNode;
use super::strip_mark;
#[allow(dead_code)]
pub struct Iter<'g, N: SkipNode> {
current: *mut N,
end: Bound<Vec<u8>>,
_guard: PhantomData<&'g N>,
}
#[allow(dead_code)]
impl<'g, N: SkipNode> Iter<'g, N> {
pub fn all(list: &SkipList<N>, guard: &'g seize::LocalGuard<'_>) -> Self {
let _ = guard;
let first = strip_mark(unsafe { (*list.head_ptr()).tower(0).load(Ordering::Acquire) });
Self {
current: first,
end: Bound::Unbounded,
_guard: PhantomData,
}
}
pub fn from(
list: &SkipList<N>,
start: &[u8],
end: Bound<Vec<u8>>,
guard: &'g seize::LocalGuard<'_>,
) -> Self {
let first = list.find_first_ge(start, guard);
Self {
current: first,
end,
_guard: PhantomData,
}
}
}
impl<'g, N: SkipNode> Iterator for Iter<'g, N> {
type Item = &'g N;
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.current.is_null() {
return None;
}
let node = unsafe { &*self.current };
self.current = strip_mark(node.tower(0).load(Ordering::Acquire));
if node.is_marked() {
continue;
}
match &self.end {
Bound::Unbounded => {}
Bound::Excluded(end) => {
if node.key_bytes() >= end.as_slice() {
self.current = std::ptr::null_mut();
return None;
}
}
Bound::Included(end) => {
if node.key_bytes() > end.as_slice() {
self.current = std::ptr::null_mut();
return None;
}
}
}
return Some(node);
}
}
}