use crate::error;
use crate::latch::{ExclusiveGuard, OptimisticGuard, SharedGuard};
use crate::optimistic::OptimisticRead;
use crate::sync::epoch::{self as epoch};
use crate::{Direction, GenericTree, Node};
use std::borrow::Borrow;
use std::mem::MaybeUninit;
use std::ops::Bound;
#[derive(Debug, PartialEq, Copy, Clone)]
enum Anchor<T> {
Start,
After(T),
Before(T),
End,
}
#[derive(Debug, PartialEq, Copy, Clone)]
enum Cursor {
After(u16),
Before(u16),
}
impl Cursor {
#[inline]
fn prev_entry(self) -> Option<(u16, Cursor)> {
match self {
Cursor::After(pos) => {
let new = if pos == 0 {
Cursor::Before(0) } else {
Cursor::After(pos - 1)
};
Some((pos, new))
}
Cursor::Before(0) => {
None
}
Cursor::Before(pos) => {
let curr = pos - 1;
let new = if curr == 0 {
Cursor::Before(0) } else {
Cursor::After(curr - 1)
};
Some((curr, new))
}
}
}
#[inline]
fn next_entry(self, leaf_len: u16) -> Option<(u16, Cursor)> {
match self {
Cursor::Before(pos) if pos < leaf_len => {
Some((pos, Cursor::Before(pos + 1)))
}
Cursor::After(pos) => {
let next = pos + 1;
if next < leaf_len {
Some((next, Cursor::Before(next + 1)))
} else {
None }
}
_ => None, }
}
#[inline]
fn peek_next_pos(self, leaf_len: u16) -> Option<u16> {
match self {
Cursor::Before(pos) if pos < leaf_len => Some(pos),
Cursor::After(pos) if (pos + 1) < leaf_len => Some(pos + 1),
_ => None,
}
}
#[inline]
fn peek_prev_pos(self) -> Option<u16> {
match self {
Cursor::After(pos) => Some(pos),
Cursor::Before(pos) if pos > 0 => Some(pos - 1),
_ => None,
}
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
enum LeafResult {
Ok,
End,
Retry,
}
#[derive(Debug)]
enum JumpResult {
Ok,
End,
Err,
}
pub struct RawSharedIter<'t, K: OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize>
{
tree: &'t GenericTree<K, V, IC, LC>,
eg: epoch::Guard,
parent: Option<(OptimisticGuard<'t, Node<K, V, IC, LC>>, u16)>,
leaf: Option<(SharedGuard<'t, Node<K, V, IC, LC>>, Cursor)>,
key_buf: MaybeUninit<K>,
val_buf: MaybeUninit<V>,
}
impl<'t, K: Clone + Ord + OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize>
RawSharedIter<'t, K, V, IC, LC>
{
pub(crate) fn new(tree: &'t GenericTree<K, V, IC, LC>) -> RawSharedIter<'t, K, V, IC, LC> {
RawSharedIter {
tree,
eg: epoch::pin(),
parent: None,
leaf: None,
key_buf: MaybeUninit::uninit(),
val_buf: MaybeUninit::uninit(),
}
}
#[inline]
fn leaf_lt<'g>(
guard: SharedGuard<'g, Node<K, V, IC, LC>>,
) -> SharedGuard<'t, Node<K, V, IC, LC>> {
unsafe { std::mem::transmute(guard) }
}
#[inline]
fn parent_lt<'g>(
guard: OptimisticGuard<'g, Node<K, V, IC, LC>>,
) -> OptimisticGuard<'t, Node<K, V, IC, LC>> {
unsafe { std::mem::transmute(guard) }
}
fn current_anchor(&self) -> Option<Anchor<K>> {
if let Some((guard, cursor)) = self.leaf.as_ref() {
let leaf = guard.as_leaf();
let anchor = match *cursor {
Cursor::Before(pos) => {
if pos >= leaf.len.load() {
if leaf.len.load() > 0 {
Anchor::After(
leaf.key_at(leaf.len.load() - 1)
.expect("leaf.len.load() > 0 implies key exists at len-1")
.clone(),
)
} else if let Some(k) = &leaf.lower_fence {
Anchor::After(k.clone())
} else {
Anchor::Start
}
} else {
Anchor::Before(
leaf.key_at(pos)
.expect("pos < leaf.len.load() implies key exists at pos")
.clone(),
)
}
}
Cursor::After(pos) => {
if pos >= leaf.len.load() {
if leaf.len.load() > 0 {
Anchor::After(
leaf.key_at(leaf.len.load() - 1)
.expect("leaf.len.load() > 0 implies key exists at len-1")
.clone(),
)
} else if let Some(k) = &leaf.upper_fence {
Anchor::After(k.clone())
} else {
Anchor::End
}
} else {
Anchor::After(
leaf.key_at(pos)
.expect("pos < leaf.len.load() implies key exists at pos")
.clone(),
)
}
}
};
Some(anchor)
} else {
None
}
}
fn restore_from_anchor(&mut self, anchor: &Anchor<K>) {
self.parent.take();
self.leaf.take();
match anchor {
Anchor::Start => self.seek_to_first(),
Anchor::End => self.seek_to_last(),
Anchor::Before(key) => self.seek(key),
Anchor::After(key) => self.seek_for_prev(key),
}
}
fn next_leaf(&mut self) -> LeafResult {
if self.leaf.is_none() {
return LeafResult::End;
}
let anchor = self.current_anchor().expect("leaf exists");
loop {
{
let (guard, cursor) = self.leaf.as_ref().unwrap();
let leaf = guard.as_leaf();
match *cursor {
Cursor::Before(pos) if pos < leaf.len.load() => {
return LeafResult::Retry;
}
Cursor::After(pos) if (pos + 1) < leaf.len.load() => {
return LeafResult::Retry;
}
_ => {}
}
if leaf.upper_fence.is_none() || self.parent.is_none() {
return LeafResult::End;
}
}
let _ = self.leaf.take();
match self.optimistic_jump(Direction::Forward) {
JumpResult::Ok => {
return LeafResult::Ok;
}
JumpResult::End => {
return LeafResult::End;
}
JumpResult::Err => {
self.restore_from_anchor(&anchor);
continue;
}
}
}
}
fn prev_leaf(&mut self) -> LeafResult {
if self.leaf.is_none() {
return LeafResult::End;
}
let anchor = self.current_anchor().expect("leaf exists");
loop {
{
let (guard, cursor) = self.leaf.as_ref().unwrap();
let leaf = guard.as_leaf();
match *cursor {
Cursor::Before(pos) if pos > 0 => {
return LeafResult::Retry;
}
Cursor::After(_pos) => {
return LeafResult::Retry;
}
_ => {}
}
if leaf.lower_fence.is_none() || self.parent.is_none() {
return LeafResult::End;
}
}
let _ = self.leaf.take();
match self.optimistic_jump(Direction::Reverse) {
JumpResult::Ok => {
return LeafResult::Ok;
}
JumpResult::End => {
return LeafResult::End;
}
JumpResult::Err => {
self.restore_from_anchor(&anchor);
continue;
}
}
}
}
fn optimistic_jump(&mut self, direction: Direction) -> JumpResult {
enum Outcome<L, P> {
Leaf(L, u16),
LeafAndParent(L, P, u16),
End,
}
let optimistic_perform = || {
if let Some((parent_guard, p_cursor)) = self.parent.as_ref() {
let bounded_pos = match direction {
Direction::Forward if *p_cursor < parent_guard.as_internal().len.load() => {
Some(*p_cursor + 1)
}
Direction::Reverse if *p_cursor > 0 => Some(*p_cursor - 1),
_ => None,
};
if let Some(pos) = bounded_pos {
let guard = {
let swip = parent_guard.as_internal().edge_at(pos)?;
GenericTree::lock_coupling(parent_guard, swip, &self.eg)?
};
assert!(guard.is_leaf());
error::Result::Ok(Outcome::Leaf(Self::leaf_lt(guard.to_shared()?), pos))
} else {
let opt =
match self.tree.find_nearest_leaf(parent_guard, direction, &self.eg)? {
Some((guard, (parent, pos))) => Outcome::LeafAndParent(
Self::leaf_lt(guard.to_shared()?),
Self::parent_lt(parent),
pos,
),
None => Outcome::End,
};
error::Result::Ok(opt)
}
} else {
error::Result::Ok(Outcome::End)
}
};
match optimistic_perform() {
Ok(Outcome::Leaf(leaf_guard, p_cursor)) => {
let l_cursor = match direction {
Direction::Forward => Cursor::Before(0),
Direction::Reverse => Cursor::After(leaf_guard.as_leaf().len.load() - 1),
};
self.leaf = Some((leaf_guard, l_cursor));
if let Some((_, p_c)) = self.parent.as_mut() {
*p_c = p_cursor;
}
JumpResult::Ok
}
Ok(Outcome::LeafAndParent(leaf_guard, parent_guard, p_cursor)) => {
let l_cursor = match direction {
Direction::Forward => Cursor::Before(0),
Direction::Reverse => Cursor::After(leaf_guard.as_leaf().len.load() - 1),
};
self.leaf = Some((leaf_guard, l_cursor));
self.parent = Some((parent_guard, p_cursor));
JumpResult::Ok
}
Ok(Outcome::End) => JumpResult::End,
Err(_) => JumpResult::Err,
}
}
pub fn seek<Q>(&mut self, key: &Q)
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().within_bounds(key) => (guard, self.parent.take()),
_ => {
let (guard, parent_opt) =
self.tree.find_shared_leaf_and_optimistic_parent(key, &self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let (pos, _) = leaf.lower_bound(key);
if pos >= leaf_len {
self.leaf = Some((guard, Cursor::Before(leaf_len)));
self.parent = parent_opt;
} else {
self.leaf = Some((guard, Cursor::Before(pos)));
self.parent = parent_opt;
}
}
pub fn seek_for_prev<Q>(&mut self, key: &Q)
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().within_bounds(key) => (guard, self.parent.take()),
_ => {
let (guard, parent_opt) =
self.tree.find_shared_leaf_and_optimistic_parent(key, &self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let (pos, exact) = leaf.lower_bound(key);
if exact {
self.leaf = Some((guard, Cursor::After(pos)));
self.parent = parent_opt;
} else if pos == 0 {
self.leaf = Some((guard, Cursor::Before(pos)));
self.parent = parent_opt;
} else if pos >= leaf_len {
self.leaf = Some((guard, Cursor::After(leaf_len - 1)));
self.parent = parent_opt;
} else {
self.leaf = Some((guard, Cursor::After(pos - 1)));
self.parent = parent_opt;
}
}
pub fn seek_exact<Q>(&mut self, key: &Q) -> bool
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().within_bounds(key) => (guard, self.parent.take()),
_ => {
let (guard, parent_opt) =
self.tree.find_shared_leaf_and_optimistic_parent(key, &self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let (pos, exact) = leaf.lower_bound(key);
if pos >= leaf_len {
self.leaf = Some((guard, Cursor::Before(leaf_len)));
self.parent = parent_opt;
} else {
self.leaf = Some((guard, Cursor::Before(pos)));
self.parent = parent_opt;
}
exact
}
pub fn seek_to_first(&mut self) {
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().lower_fence.is_none() => {
(guard, self.parent.take())
}
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_first_shared_leaf_and_optimistic_parent(&self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
self.leaf = Some((guard, Cursor::Before(0)));
self.parent = parent_opt;
}
pub fn seek_to_last(&mut self) {
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().upper_fence.is_none() => {
(guard, self.parent.take())
}
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_last_shared_leaf_and_optimistic_parent(&self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf_len = guard.as_leaf().len.load();
self.leaf = Some((guard, Cursor::Before(leaf_len)));
self.parent = parent_opt;
}
#[inline]
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<(&K, &V)> {
loop {
let opt = match self.leaf.as_ref() {
Some((guard, cursor)) => cursor.next_entry(guard.as_leaf().len.load()),
None => return None,
};
if let Some((curr_pos, new_cursor)) = opt {
let (guard, cursor) = self.leaf.as_mut().unwrap();
let leaf = guard.as_leaf();
*cursor = new_cursor;
let k = unsafe { leaf.keys.load_into(curr_pos as usize, &mut self.key_buf) };
let v = unsafe { leaf.values.load_into(curr_pos as usize, &mut self.val_buf) };
return Some((k, v));
} else {
match self.next_leaf() {
LeafResult::Ok | LeafResult::Retry => {
continue;
}
LeafResult::End => {
return None;
}
}
}
}
}
#[inline]
pub fn prev(&mut self) -> Option<(&K, &V)> {
loop {
let opt = match self.leaf.as_ref() {
Some((_guard, cursor)) => cursor.prev_entry(),
None => return None,
};
if let Some((curr_pos, new_cursor)) = opt {
let (guard, cursor) = self.leaf.as_mut().unwrap();
let leaf = guard.as_leaf();
*cursor = new_cursor;
let k = unsafe { leaf.keys.load_into(curr_pos as usize, &mut self.key_buf) };
let v = unsafe { leaf.values.load_into(curr_pos as usize, &mut self.val_buf) };
return Some((k, v));
} else {
match self.prev_leaf() {
LeafResult::Ok | LeafResult::Retry => {
continue;
}
LeafResult::End => {
return None;
}
}
}
}
}
#[inline]
pub fn peek(&mut self) -> Option<(&K, &V)> {
loop {
let pos_opt = match self.leaf.as_ref() {
Some((guard, cursor)) => cursor.peek_next_pos(guard.as_leaf().len.load()),
None => return None,
};
if let Some(pos) = pos_opt {
let (guard, _) = self.leaf.as_ref().unwrap();
let leaf = guard.as_leaf();
let k = unsafe { leaf.keys.load_into(pos as usize, &mut self.key_buf) };
let v = unsafe { leaf.values.load_into(pos as usize, &mut self.val_buf) };
return Some((k, v));
} else {
match self.next_leaf() {
LeafResult::Ok | LeafResult::Retry => continue,
LeafResult::End => return None,
}
}
}
}
#[inline]
pub fn peek_prev(&mut self) -> Option<(&K, &V)> {
loop {
let pos_opt = match self.leaf.as_ref() {
Some((_, cursor)) => cursor.peek_prev_pos(),
None => return None,
};
if let Some(pos) = pos_opt {
let (guard, _) = self.leaf.as_ref().unwrap();
let leaf = guard.as_leaf();
let k = unsafe { leaf.keys.load_into(pos as usize, &mut self.key_buf) };
let v = unsafe { leaf.values.load_into(pos as usize, &mut self.val_buf) };
return Some((k, v));
} else {
match self.prev_leaf() {
LeafResult::Ok | LeafResult::Retry => continue,
LeafResult::End => return None,
}
}
}
}
#[inline]
pub fn for_each_in_leaf<F>(&mut self, mut f: F) -> bool
where
F: FnMut(&K, &V),
{
let Some((guard, cursor)) = self.leaf.as_mut() else {
return false;
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let start = match *cursor {
Cursor::Before(pos) => pos,
Cursor::After(pos) => pos.saturating_add(1),
};
for i in start..leaf_len {
let mut key_buf: MaybeUninit<K> = MaybeUninit::uninit();
let mut val_buf: MaybeUninit<V> = MaybeUninit::uninit();
let k = unsafe { leaf.keys.load_into(i as usize, &mut key_buf) };
let v = unsafe { leaf.values.load_into(i as usize, &mut val_buf) };
f(k, v);
}
*cursor = Cursor::Before(leaf_len);
leaf.upper_fence.is_some()
}
}
pub struct RawExclusiveIter<
't,
K: OptimisticRead,
V: OptimisticRead,
const IC: usize,
const LC: usize,
> {
tree: &'t GenericTree<K, V, IC, LC>,
eg: epoch::Guard,
parent: Option<(OptimisticGuard<'t, Node<K, V, IC, LC>>, u16)>,
leaf: Option<(ExclusiveGuard<'t, Node<K, V, IC, LC>>, Cursor)>,
buffer: Option<(K, V, u16)>,
}
impl<'t, K: OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize> Drop
for RawExclusiveIter<'t, K, V, IC, LC>
{
fn drop(&mut self) {
if let Some((_k, v, pos)) = self.buffer.take() {
if let Some((guard, _)) = self.leaf.as_ref() {
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = unsafe { crate::Node::as_leaf_ptr_mut(node_ptr) };
unsafe {
crate::LeafNode::swap_value_at_raw(leaf_ptr, pos, v, &self.eg);
}
}
}
}
}
impl<
't,
K: Clone + Ord + OptimisticRead,
V: Clone + OptimisticRead,
const IC: usize,
const LC: usize,
> RawExclusiveIter<'t, K, V, IC, LC>
{
pub(crate) fn new(tree: &'t GenericTree<K, V, IC, LC>) -> RawExclusiveIter<'t, K, V, IC, LC> {
RawExclusiveIter {
tree,
eg: epoch::pin(),
parent: None,
leaf: None,
buffer: None,
}
}
fn flush_buffer(&mut self) {
if let Some((_k, v, pos)) = self.buffer.take() {
if let Some((guard, _)) = self.leaf.as_ref() {
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = unsafe { crate::Node::as_leaf_ptr_mut(node_ptr) };
unsafe {
crate::LeafNode::swap_value_at_raw(leaf_ptr, pos, v, &self.eg);
}
}
}
}
#[inline]
fn leaf_lt<'g>(
guard: ExclusiveGuard<'g, Node<K, V, IC, LC>>,
) -> ExclusiveGuard<'t, Node<K, V, IC, LC>> {
unsafe { std::mem::transmute(guard) }
}
#[inline]
fn parent_lt<'g>(
guard: OptimisticGuard<'g, Node<K, V, IC, LC>>,
) -> OptimisticGuard<'t, Node<K, V, IC, LC>> {
unsafe { std::mem::transmute(guard) }
}
fn current_anchor(&self) -> Option<Anchor<K>> {
if let Some((guard, cursor)) = self.leaf.as_ref() {
let leaf = guard.as_leaf();
let anchor = match *cursor {
Cursor::Before(pos) => {
if pos >= leaf.len.load() {
if leaf.len.load() > 0 {
Anchor::After(
leaf.key_at(leaf.len.load() - 1)
.expect("leaf.len.load() > 0 implies key exists at len-1")
.clone(),
)
} else if let Some(k) = &leaf.lower_fence {
Anchor::After(k.clone())
} else {
Anchor::Start
}
} else {
Anchor::Before(
leaf.key_at(pos)
.expect("pos < leaf.len.load() implies key exists at pos")
.clone(),
)
}
}
Cursor::After(pos) => {
if pos >= leaf.len.load() {
if leaf.len.load() > 0 {
Anchor::After(
leaf.key_at(leaf.len.load() - 1)
.expect("leaf.len.load() > 0 implies key exists at len-1")
.clone(),
)
} else if let Some(k) = &leaf.upper_fence {
Anchor::After(k.clone())
} else {
Anchor::End
}
} else {
Anchor::After(
leaf.key_at(pos)
.expect("pos < leaf.len.load() implies key exists at pos")
.clone(),
)
}
}
};
Some(anchor)
} else {
None
}
}
fn restore_from_anchor(&mut self, anchor: &Anchor<K>) {
self.parent.take();
self.leaf.take();
match anchor {
Anchor::Start => self.seek_to_first(),
Anchor::End => self.seek_to_last(),
Anchor::Before(key) => self.seek(key),
Anchor::After(key) => self.seek_for_prev(key),
}
}
fn next_leaf(&mut self) -> LeafResult {
if self.leaf.is_none() {
return LeafResult::End;
}
let anchor = self.current_anchor().expect("leaf exists");
loop {
{
let (guard, cursor) = self.leaf.as_ref().unwrap();
let leaf = guard.as_leaf();
match *cursor {
Cursor::Before(pos) if pos < leaf.len.load() => {
return LeafResult::Retry;
}
Cursor::After(pos) if (pos + 1) < leaf.len.load() => {
return LeafResult::Retry;
}
_ => {}
}
if leaf.upper_fence.is_none() || self.parent.is_none() {
return LeafResult::End;
}
}
let _ = self.leaf.take();
match self.optimistic_jump(Direction::Forward) {
JumpResult::Ok => {
return LeafResult::Ok;
}
JumpResult::End => {
return LeafResult::End;
}
JumpResult::Err => {
self.restore_from_anchor(&anchor);
continue;
}
}
}
}
fn prev_leaf(&mut self) -> LeafResult {
if self.leaf.is_none() {
return LeafResult::End;
}
let anchor = self.current_anchor().expect("leaf exists");
loop {
{
let (guard, cursor) = self.leaf.as_ref().unwrap();
let leaf = guard.as_leaf();
match *cursor {
Cursor::Before(pos) if pos > 0 => {
return LeafResult::Retry;
}
Cursor::After(_pos) => {
return LeafResult::Retry;
}
_ => {}
}
if leaf.lower_fence.is_none() || self.parent.is_none() {
return LeafResult::End;
}
}
let _ = self.leaf.take();
match self.optimistic_jump(Direction::Reverse) {
JumpResult::Ok => {
return LeafResult::Ok;
}
JumpResult::End => {
return LeafResult::End;
}
JumpResult::Err => {
self.restore_from_anchor(&anchor);
continue;
}
}
}
}
fn optimistic_jump(&mut self, direction: Direction) -> JumpResult {
enum Outcome<L, P> {
Leaf(L, u16),
LeafAndParent(L, P, u16),
End,
}
let optimistic_perform = || {
if let Some((parent_guard, p_cursor)) = self.parent.as_ref() {
let bounded_pos = match direction {
Direction::Forward if *p_cursor < parent_guard.as_internal().len.load() => {
Some(*p_cursor + 1)
}
Direction::Reverse if *p_cursor > 0 => Some(*p_cursor - 1),
_ => None,
};
if let Some(pos) = bounded_pos {
let guard = {
let swip = parent_guard.as_internal().edge_at(pos)?;
GenericTree::lock_coupling(parent_guard, swip, &self.eg)?
};
assert!(guard.is_leaf());
error::Result::Ok(Outcome::Leaf(Self::leaf_lt(guard.to_exclusive()?), pos))
} else {
let opt =
match self.tree.find_nearest_leaf(parent_guard, direction, &self.eg)? {
Some((guard, (parent, pos))) => Outcome::LeafAndParent(
Self::leaf_lt(guard.to_exclusive()?),
Self::parent_lt(parent),
pos,
),
None => Outcome::End,
};
error::Result::Ok(opt)
}
} else {
error::Result::Ok(Outcome::End)
}
};
match optimistic_perform() {
Ok(Outcome::Leaf(leaf_guard, p_cursor)) => {
let l_cursor = match direction {
Direction::Forward => Cursor::Before(0),
Direction::Reverse => Cursor::After(leaf_guard.as_leaf().len.load() - 1),
};
self.leaf = Some((leaf_guard, l_cursor));
if let Some((_, p_c)) = self.parent.as_mut() {
*p_c = p_cursor;
}
JumpResult::Ok
}
Ok(Outcome::LeafAndParent(leaf_guard, parent_guard, p_cursor)) => {
let l_cursor = match direction {
Direction::Forward => Cursor::Before(0),
Direction::Reverse => Cursor::After(leaf_guard.as_leaf().len.load() - 1),
};
self.leaf = Some((leaf_guard, l_cursor));
self.parent = Some((parent_guard, p_cursor));
JumpResult::Ok
}
Ok(Outcome::End) => JumpResult::End,
Err(_) => JumpResult::Err,
}
}
pub fn seek<Q>(&mut self, key: &Q)
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().within_bounds(key) => (guard, self.parent.take()),
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_exclusive_leaf_and_optimistic_parent(key, &self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let (pos, _) = leaf.lower_bound(key);
if pos >= leaf_len {
self.leaf = Some((guard, Cursor::Before(leaf_len)));
self.parent = parent_opt;
} else {
self.leaf = Some((guard, Cursor::Before(pos)));
self.parent = parent_opt;
}
}
pub fn seek_for_prev<Q>(&mut self, key: &Q)
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().within_bounds(key) => (guard, self.parent.take()),
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_exclusive_leaf_and_optimistic_parent(key, &self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let (pos, exact) = leaf.lower_bound(key);
if exact {
self.leaf = Some((guard, Cursor::After(pos)));
self.parent = parent_opt;
} else if pos == 0 {
self.leaf = Some((guard, Cursor::Before(pos)));
self.parent = parent_opt;
} else if pos >= leaf_len {
self.leaf = Some((guard, Cursor::After(leaf_len - 1)));
self.parent = parent_opt;
} else {
self.leaf = Some((guard, Cursor::After(pos - 1)));
self.parent = parent_opt;
}
}
pub fn seek_exact<Q>(&mut self, key: &Q) -> bool
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().within_bounds(key) => (guard, self.parent.take()),
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_exclusive_leaf_and_optimistic_parent(key, &self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf = guard.as_leaf();
let leaf_len = leaf.len.load();
let (pos, exact) = leaf.lower_bound(key);
if pos >= leaf_len {
self.leaf = Some((guard, Cursor::Before(leaf_len)));
self.parent = parent_opt;
} else {
self.leaf = Some((guard, Cursor::Before(pos)));
self.parent = parent_opt;
}
exact
}
pub fn seek_to_first(&mut self) {
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().lower_fence.is_none() => {
(guard, self.parent.take())
}
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_first_exclusive_leaf_and_optimistic_parent(&self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
self.leaf = Some((guard, Cursor::Before(0)));
self.parent = parent_opt;
}
pub fn seek_to_last(&mut self) {
let (guard, parent_opt) = match self.leaf.take() {
Some((guard, _)) if guard.as_leaf().upper_fence.is_none() => {
(guard, self.parent.take())
}
_ => {
self.parent.take();
let (guard, parent_opt) =
self.tree.find_last_exclusive_leaf_and_optimistic_parent(&self.eg);
(
Self::leaf_lt(guard),
parent_opt.map(|(parent, pos)| (Self::parent_lt(parent), pos)),
)
}
};
let leaf_len = guard.as_leaf().len.load();
self.leaf = Some((guard, Cursor::Before(leaf_len)));
self.parent = parent_opt;
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
if self.seek_exact(&key) {
let (guard, cursor) = self.leaf.as_mut().expect("seek_exact set up leaf");
let pos = match *cursor {
Cursor::Before(p) => p,
Cursor::After(p) => p + 1,
};
let leaf_node_ptr = guard.as_mut_ptr();
let leaf_ptr = unsafe {
crate::Node::as_leaf_ptr_mut(leaf_node_ptr)
};
let old = unsafe { crate::LeafNode::swap_value_at_raw(leaf_ptr, pos, value, &self.eg) };
*cursor = Cursor::After(pos);
Some(old)
} else {
self.insert_here(key, value);
None
}
}
pub fn insert_here(&mut self, key: K, value: V) {
'start: loop {
let (guard, cursor) = self.leaf.as_mut().expect("insert_here requires prior seek");
if guard.as_leaf().has_space() {
match *cursor {
Cursor::Before(pos) => {
unsafe {
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = crate::Node::as_leaf_ptr_mut(node_ptr);
crate::LeafNode::insert_at_raw(leaf_ptr, pos, key, value)
.expect("just checked for space");
}
}
Cursor::After(_) => {
unreachable!("seek_exact always sets cursor to before");
}
}
break;
} else {
self.parent.take();
let (guard, _cursor) = self.leaf.take().expect("just checked");
let mut guard = guard.unlock();
loop {
let perform_split = || {
if !guard.as_leaf().has_space() {
guard.recheck()?;
self.tree.try_split(&guard, &self.eg)?;
}
error::Result::Ok(())
};
match perform_split() {
Ok(_) => {
break;
}
Err(error::Error::Reclaimed) => {
if !self.seek_exact(&key) {
continue 'start;
} else {
return;
}
}
Err(_) => {
guard = guard.latch().optimistic_or_spin();
continue;
}
}
}
if !self.seek_exact(&key) {
continue 'start;
} else {
return;
}
}
}
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q> + Ord,
Q: ?Sized + Ord,
{
if self.seek_exact(key) {
Some(self.remove_next().expect("just seeked for remove"))
} else {
None
}
}
pub fn remove_here(&mut self) -> Option<(K, V)> {
match self.leaf.as_mut() {
Some((guard, cursor)) => {
let pos = match cursor {
Cursor::After(pos) => *pos,
Cursor::Before(_) => return None, };
let leaf = guard.as_leaf_mut();
if pos >= leaf.len.load() {
return None;
}
let removed = unsafe {
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = crate::Node::as_leaf_ptr_mut(node_ptr);
crate::LeafNode::remove_at_raw(leaf_ptr, pos, &self.eg)
};
*cursor = Cursor::Before(pos);
if guard.is_underfull() {
let removed_key = removed.0.clone();
self.parent.take();
let (guard, _cursor) = self.leaf.take().expect("just checked");
let guard = guard.unlock();
let _ = self.tree.try_merge(&guard, &self.eg);
self.seek(&removed_key);
}
Some(removed)
}
None => None,
}
}
fn remove_next(&mut self) -> Option<(K, V)> {
match self.leaf.as_mut() {
Some((guard, cursor)) => {
let leaf = guard.as_leaf_mut();
let removed = match cursor {
Cursor::Before(pos) => {
let curr_pos = *pos;
if curr_pos < leaf.len.load() {
Some(unsafe {
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = crate::Node::as_leaf_ptr_mut(node_ptr);
crate::LeafNode::remove_at_raw(leaf_ptr, curr_pos, &self.eg)
})
} else {
None
}
}
Cursor::After(pos) => {
let pos = *pos;
let curr_pos = pos + 1;
if curr_pos < leaf.len.load() {
Some(unsafe {
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = crate::Node::as_leaf_ptr_mut(node_ptr);
crate::LeafNode::remove_at_raw(leaf_ptr, curr_pos, &self.eg)
})
} else {
None
}
}
};
if let Some((removed_key, _)) = removed.as_ref() {
if guard.is_underfull() {
self.parent.take();
let (guard, _cursor) = self.leaf.take().expect("just seeked");
let guard = guard.unlock();
let _ = self.tree.try_merge(&guard, &self.eg);
self.seek(removed_key);
}
}
removed
}
None => None,
}
}
#[inline]
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<(&K, &mut V)> {
self.flush_buffer();
loop {
let opt = match self.leaf.as_ref() {
Some((guard, cursor)) => cursor.next_entry(guard.as_leaf().len.load()),
None => return None,
};
if let Some((curr_pos, new_cursor)) = opt {
let (guard, cursor) = self.leaf.as_mut().unwrap();
let leaf = guard.as_leaf();
*cursor = new_cursor;
let (k, v) = unsafe { leaf.kv_at_unchecked(curr_pos) };
self.buffer = Some((k, v, curr_pos));
let (k_ref, v_ref, _) = self.buffer.as_mut().unwrap();
return Some((k_ref, v_ref));
} else {
match self.next_leaf() {
LeafResult::Ok | LeafResult::Retry => {
continue;
}
LeafResult::End => {
return None;
}
}
}
}
}
#[inline]
pub fn prev(&mut self) -> Option<(&K, &mut V)> {
self.flush_buffer();
loop {
let opt = match self.leaf.as_ref() {
Some((_guard, cursor)) => cursor.prev_entry(),
None => return None,
};
if let Some((curr_pos, new_cursor)) = opt {
let (guard, cursor) = self.leaf.as_mut().unwrap();
let leaf = guard.as_leaf();
*cursor = new_cursor;
let (k, v) = unsafe { leaf.kv_at_unchecked(curr_pos) };
self.buffer = Some((k, v, curr_pos));
let (k_ref, v_ref, _) = self.buffer.as_mut().unwrap();
return Some((k_ref, v_ref));
} else {
match self.prev_leaf() {
LeafResult::Ok | LeafResult::Retry => {
continue;
}
LeafResult::End => {
return None;
}
}
}
}
}
#[inline]
pub fn peek(&mut self) -> Option<(&K, &mut V)> {
self.flush_buffer();
loop {
let pos_opt = match self.leaf.as_ref() {
Some((guard, cursor)) => cursor.peek_next_pos(guard.as_leaf().len.load()),
None => return None,
};
if let Some(pos) = pos_opt {
let (guard, _) = self.leaf.as_ref().unwrap();
let (k, v) = unsafe { guard.as_leaf().kv_at_unchecked(pos) };
self.buffer = Some((k, v, pos));
let (k_ref, v_ref, _) = self.buffer.as_mut().unwrap();
return Some((k_ref, v_ref));
} else {
match self.next_leaf() {
LeafResult::Ok | LeafResult::Retry => continue,
LeafResult::End => return None,
}
}
}
}
#[inline]
pub fn peek_prev(&mut self) -> Option<(&K, &mut V)> {
self.flush_buffer();
loop {
let pos_opt = match self.leaf.as_ref() {
Some((_, cursor)) => cursor.peek_prev_pos(),
None => return None,
};
if let Some(pos) = pos_opt {
let (guard, _) = self.leaf.as_ref().unwrap();
let (k, v) = unsafe { guard.as_leaf().kv_at_unchecked(pos) };
self.buffer = Some((k, v, pos));
let (k_ref, v_ref, _) = self.buffer.as_mut().unwrap();
return Some((k_ref, v_ref));
} else {
match self.prev_leaf() {
LeafResult::Ok | LeafResult::Retry => continue,
LeafResult::End => return None,
}
}
}
}
#[inline]
pub fn for_each_in_leaf<F>(&mut self, mut f: F) -> bool
where
F: FnMut(&K, &mut V),
{
let Some((guard, cursor)) = self.leaf.as_mut() else {
return false;
};
let leaf_len = guard.as_leaf().len.load();
let upper_fence_some = guard.as_leaf().upper_fence.is_some();
let start = match *cursor {
Cursor::Before(pos) => pos,
Cursor::After(pos) => pos.saturating_add(1),
};
let node_ptr = guard.as_mut_ptr();
let leaf_ptr = unsafe { crate::Node::as_leaf_ptr_mut(node_ptr) };
for i in start..leaf_len {
let (k, mut v) = unsafe { guard.as_leaf().kv_at_unchecked(i) };
f(&k, &mut v);
unsafe {
crate::LeafNode::swap_value_at_raw(leaf_ptr, i, v, &self.eg);
}
}
*cursor = Cursor::Before(leaf_len);
upper_fence_some
}
}
pub struct Range<'t, K: OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize> {
iter: RawSharedIter<'t, K, V, IC, LC>,
upper_bound: Bound<K>,
finished: bool,
}
impl<'t, K: Clone + Ord + OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize>
Range<'t, K, V, IC, LC>
{
pub(crate) fn new<Q>(
tree: &'t GenericTree<K, V, IC, LC>,
min: Bound<&Q>,
max: Bound<&Q>,
) -> Range<'t, K, V, IC, LC>
where
K: Borrow<Q>,
Q: ?Sized + Ord,
{
let mut iter = tree.raw_iter();
let upper_bound = match max {
Bound::Unbounded => Bound::Unbounded,
Bound::Included(k) => {
iter.seek(k);
match iter.next() {
Some((key, _)) if key.borrow() == k => Bound::Included(key.clone()),
Some((key, _)) => {
Bound::Excluded(key.clone())
}
None => Bound::Unbounded, }
}
Bound::Excluded(k) => {
iter.seek(k);
match iter.next() {
Some((key, _)) if key.borrow() == k => Bound::Excluded(key.clone()),
Some((key, _)) => {
Bound::Excluded(key.clone())
}
None => Bound::Unbounded, }
}
};
match min {
Bound::Unbounded => iter.seek_to_first(),
Bound::Included(k) => iter.seek(k),
Bound::Excluded(k) => {
if iter.seek_exact(k) {
let _ = iter.next(); }
}
}
Range {
iter,
upper_bound,
finished: false,
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<(&K, &V)> {
if self.finished {
return None;
}
match self.iter.next() {
Some((k, v)) => {
let within_bounds = match &self.upper_bound {
Bound::Unbounded => true,
Bound::Included(max) => k <= max,
Bound::Excluded(max) => k < max,
};
if within_bounds {
Some((k, v))
} else {
self.finished = true;
None
}
}
None => {
self.finished = true;
None
}
}
}
pub fn prev(&mut self) -> Option<(&K, &V)> {
self.iter.prev()
}
pub fn peek(&mut self) -> Option<(&K, &V)> {
if self.finished {
return None;
}
match self.iter.peek() {
Some((k, v)) => {
let within_bounds = match &self.upper_bound {
Bound::Unbounded => true,
Bound::Included(max) => k <= max,
Bound::Excluded(max) => k < max,
};
if within_bounds {
Some((k, v))
} else {
None
}
}
None => None,
}
}
pub fn peek_prev(&mut self) -> Option<(&K, &V)> {
self.iter.peek_prev()
}
}
pub struct RangeRev<'t, K: OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize> {
iter: RawSharedIter<'t, K, V, IC, LC>,
lower_bound: Bound<K>,
finished: bool,
}
impl<'t, K: Clone + Ord + OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize>
RangeRev<'t, K, V, IC, LC>
{
pub(crate) fn new<Q>(
tree: &'t GenericTree<K, V, IC, LC>,
min: Bound<&Q>,
max: Bound<&Q>,
) -> RangeRev<'t, K, V, IC, LC>
where
K: Borrow<Q>,
Q: ?Sized + Ord,
{
let mut iter = tree.raw_iter();
let lower_bound = match min {
Bound::Unbounded => Bound::Unbounded,
Bound::Included(k) => {
iter.seek(k);
match iter.next() {
Some((key, _)) if key.borrow() == k => Bound::Included(key.clone()),
Some((key, _)) => {
Bound::Included(key.clone())
}
None => Bound::Unbounded, }
}
Bound::Excluded(k) => {
iter.seek(k);
match iter.next() {
Some((key, _)) if key.borrow() == k => Bound::Excluded(key.clone()),
Some((key, _)) => {
Bound::Included(key.clone())
}
None => Bound::Unbounded, }
}
};
match max {
Bound::Unbounded => iter.seek_to_last(),
Bound::Included(k) => {
iter.seek_for_prev(k);
}
Bound::Excluded(k) => {
iter.seek_for_prev(k);
if let Some((key, _)) = iter.peek_prev() {
if key.borrow() == k {
let _ = iter.prev(); }
}
}
}
RangeRev {
iter,
lower_bound,
finished: false,
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<(&K, &V)> {
if self.finished {
return None;
}
match self.iter.prev() {
Some((k, v)) => {
let within_bounds = match &self.lower_bound {
Bound::Unbounded => true,
Bound::Included(min) => k >= min,
Bound::Excluded(min) => k > min,
};
if within_bounds {
Some((k, v))
} else {
self.finished = true;
None
}
}
None => {
self.finished = true;
None
}
}
}
pub fn prev(&mut self) -> Option<(&K, &V)> {
self.iter.next()
}
pub fn peek(&mut self) -> Option<(&K, &V)> {
if self.finished {
return None;
}
match self.iter.peek_prev() {
Some((k, v)) => {
let within_bounds = match &self.lower_bound {
Bound::Unbounded => true,
Bound::Included(min) => k >= min,
Bound::Excluded(min) => k > min,
};
if within_bounds {
Some((k, v))
} else {
None
}
}
None => None,
}
}
pub fn peek_prev(&mut self) -> Option<(&K, &V)> {
self.iter.peek()
}
}
pub struct Keys<'t, K: OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize> {
iter: RawSharedIter<'t, K, V, IC, LC>,
}
impl<'t, K: Clone + Ord + OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize>
Keys<'t, K, V, IC, LC>
{
pub(crate) fn new(tree: &'t GenericTree<K, V, IC, LC>) -> Keys<'t, K, V, IC, LC> {
let mut iter = tree.raw_iter();
iter.seek_to_first();
Keys {
iter,
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<&K> {
self.iter.next().map(|(k, _)| k)
}
pub fn prev(&mut self) -> Option<&K> {
self.iter.prev().map(|(k, _)| k)
}
}
pub struct Values<'t, K: OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize> {
iter: RawSharedIter<'t, K, V, IC, LC>,
}
impl<'t, K: Clone + Ord + OptimisticRead, V: OptimisticRead, const IC: usize, const LC: usize>
Values<'t, K, V, IC, LC>
{
pub(crate) fn new(tree: &'t GenericTree<K, V, IC, LC>) -> Values<'t, K, V, IC, LC> {
let mut iter = tree.raw_iter();
iter.seek_to_first();
Values {
iter,
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<&V> {
self.iter.next().map(|(_, v)| v)
}
pub fn prev(&mut self) -> Option<&V> {
self.iter.prev().map(|(_, v)| v)
}
}
#[cfg(test)]
mod tests {
use crate::Tree;
#[test]
fn iter_empty_tree_next_returns_none() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter();
iter.seek_to_first();
assert!(iter.next().is_none());
}
#[test]
fn iter_empty_tree_prev_returns_none() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter();
iter.seek_to_last();
assert!(iter.prev().is_none());
}
#[test]
fn iter_mut_empty_tree_next_returns_none() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter_mut();
iter.seek_to_first();
assert!(iter.next().is_none());
}
#[test]
fn iter_mut_empty_tree_prev_returns_none() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter_mut();
iter.seek_to_last();
assert!(iter.prev().is_none());
}
#[test]
fn iter_single_element_forward() {
let tree: Tree<i32, i32> = Tree::new();
tree.insert(42, 100);
let mut iter = tree.raw_iter();
iter.seek_to_first();
let (k, v) = iter.next().unwrap();
assert_eq!(*k, 42);
assert_eq!(*v, 100);
assert!(iter.next().is_none());
}
#[test]
fn iter_single_element_backward() {
let tree: Tree<i32, i32> = Tree::new();
tree.insert(42, 100);
let mut iter = tree.raw_iter();
iter.seek_to_last();
let (k, v) = iter.prev().unwrap();
assert_eq!(*k, 42);
assert_eq!(*v, 100);
assert!(iter.prev().is_none());
}
#[test]
fn seek_to_existing_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i * 10, i);
}
let mut iter = tree.raw_iter();
iter.seek(&50);
let (k, v) = iter.next().unwrap();
assert_eq!(*k, 50);
assert_eq!(*v, 5);
}
#[test]
fn seek_to_nonexisting_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i * 10, i);
}
let mut iter = tree.raw_iter();
iter.seek(&55);
let (k, v) = iter.next().unwrap();
assert_eq!(*k, 60);
assert_eq!(*v, 6);
}
#[test]
fn seek_exact_returns_true_for_existing() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i * 10, i);
}
let mut iter = tree.raw_iter();
let found = iter.seek_exact(&50);
assert!(found);
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 50);
}
#[test]
fn seek_exact_returns_false_for_nonexisting() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i * 10, i);
}
let mut iter = tree.raw_iter();
let found = iter.seek_exact(&55);
assert!(!found);
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 60);
}
#[test]
fn seek_for_prev_existing_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i * 10, i);
}
let mut iter = tree.raw_iter();
iter.seek_for_prev(&50);
let (k, v) = iter.prev().unwrap();
assert_eq!(*k, 50);
assert_eq!(*v, 5);
}
#[test]
fn seek_for_prev_nonexisting_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i * 10, i);
}
let mut iter = tree.raw_iter();
iter.seek_for_prev(&55);
let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 50);
let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 40);
}
#[test]
fn seek_to_first_positions_at_beginning() {
let tree: Tree<i32, i32> = Tree::new();
for i in (0..10).rev() {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
let (k, v) = iter.next().unwrap();
assert_eq!(*k, 0);
assert_eq!(*v, 0);
}
#[test]
fn seek_to_last_positions_at_end() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_last();
assert!(iter.next().is_none());
let (k, v) = iter.prev().unwrap();
assert_eq!(*k, 9);
assert_eq!(*v, 90);
}
#[test]
fn mixed_next_and_prev() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
assert_eq!(*iter.next().unwrap().0, 5);
assert_eq!(*iter.next().unwrap().0, 6);
assert_eq!(*iter.prev().unwrap().0, 6);
assert_eq!(*iter.prev().unwrap().0, 5);
assert_eq!(*iter.prev().unwrap().0, 4);
assert_eq!(*iter.next().unwrap().0, 4);
}
#[test]
fn reverse_from_middle() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
iter.next();
let mut collected: Vec<i32> = Vec::new();
while let Some((k, _)) = iter.prev() {
collected.push(*k);
}
assert_eq!(collected, vec![5, 4, 3, 2, 1, 0]);
}
#[test]
fn forward_then_full_reverse() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..5 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
while iter.next().is_some() {}
let mut collected: Vec<i32> = Vec::new();
while let Some((k, _)) = iter.prev() {
collected.push(*k);
}
assert_eq!(collected, vec![4, 3, 2, 1, 0]);
}
#[test]
fn full_forward_iteration() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..100 {
tree.insert(i, i * 2);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
let mut count = 0;
while let Some((k, v)) = iter.next() {
assert_eq!(*k, count);
assert_eq!(*v, count * 2);
count += 1;
}
assert_eq!(count, 100);
}
#[test]
fn full_reverse_iteration() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..100 {
tree.insert(i, i * 2);
}
let mut iter = tree.raw_iter();
iter.seek_to_last();
let mut count = 99i32;
while let Some((k, v)) = iter.prev() {
assert_eq!(*k, count);
assert_eq!(*v, count * 2);
count -= 1;
}
assert_eq!(count, -1);
}
#[test]
fn iteration_crosses_leaf_boundaries_forward() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..200 {
tree.insert(i, i);
}
assert!(tree.height() > 1, "Tree should have multiple levels");
let mut iter = tree.raw_iter();
iter.seek_to_first();
let mut count = 0;
while let Some((k, _)) = iter.next() {
assert_eq!(*k, count);
count += 1;
}
assert_eq!(count, 200);
}
#[test]
fn iteration_crosses_leaf_boundaries_reverse() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..200 {
tree.insert(i, i);
}
assert!(tree.height() > 1);
let mut iter = tree.raw_iter();
iter.seek_to_last();
let mut count = 199i32;
while let Some((k, _)) = iter.prev() {
assert_eq!(*k, count);
count -= 1;
}
assert_eq!(count, -1);
}
#[test]
fn for_each_in_leaf_processes_all_entries() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
let mut collected = Vec::new();
let has_more = iter.for_each_in_leaf(|k, v| {
collected.push((*k, *v));
});
assert_eq!(collected.len(), 10);
assert_eq!(collected[0], (0, 0));
assert_eq!(collected[9], (9, 90));
assert!(!has_more);
}
#[test]
fn for_each_in_leaf_respects_cursor_position() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
let mut collected = Vec::new();
iter.for_each_in_leaf(|k, v| {
collected.push((*k, *v));
});
assert_eq!(collected[0], (5, 50));
assert_eq!(collected.len(), 5); }
#[test]
fn for_each_in_leaf_after_next() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
iter.next();
iter.next();
iter.next();
let mut collected = Vec::new();
iter.for_each_in_leaf(|k, v| {
collected.push((*k, *v));
});
assert_eq!(collected[0], (3, 30));
assert_eq!(collected.len(), 7); }
#[test]
fn for_each_in_leaf_empty_after_exhausted() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..5 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
iter.for_each_in_leaf(|_, _| {});
let mut count = 0;
iter.for_each_in_leaf(|_, _| {
count += 1;
});
assert_eq!(count, 0);
}
#[test]
fn for_each_in_leaf_unpositioned_iterator() {
let tree: Tree<i32, i32> = Tree::new();
tree.insert(1, 10);
let mut iter = tree.raw_iter();
let has_more = iter.for_each_in_leaf(|_, _| {
panic!("Should not be called");
});
assert!(!has_more);
}
#[test]
fn for_each_in_leaf_mut_can_modify_values() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
{
let mut iter = tree.raw_iter_mut();
iter.seek_to_first();
iter.for_each_in_leaf(|_, v| {
*v *= 2;
});
}
for i in 0..10 {
let val = tree.lookup(&i, |v| *v).unwrap();
assert_eq!(val, i * 2);
}
}
#[test]
fn for_each_in_leaf_crosses_multiple_leaves() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..200 {
tree.insert(i, i);
}
assert!(tree.height() > 1, "Tree should have multiple levels");
let mut iter = tree.raw_iter();
iter.seek_to_first();
let mut total_count = 0;
let mut leaf_count = 0;
loop {
let mut leaf_entries = 0;
let has_more = iter.for_each_in_leaf(|_, _| {
leaf_entries += 1;
});
total_count += leaf_entries;
leaf_count += 1;
if !has_more {
break;
}
if iter.next().is_some() {
total_count += 1; } else {
break;
}
}
assert_eq!(total_count, 200);
assert!(leaf_count > 1, "Should have visited multiple leaves");
}
#[test]
fn exclusive_iter_can_modify_values() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
{
let mut iter = tree.raw_iter_mut();
iter.seek_to_first();
while let Some((_, v)) = iter.next() {
*v *= 2;
}
}
for i in 0..10 {
assert_eq!(tree.lookup(&i, |v| *v), Some(i * 2));
}
}
#[test]
fn exclusive_iter_insert() {
let tree: Tree<i32, i32> = Tree::new();
{
let mut iter = tree.raw_iter_mut();
iter.insert(5, 50);
iter.insert(3, 30);
iter.insert(7, 70);
}
assert_eq!(tree.lookup(&3, |v| *v), Some(30));
assert_eq!(tree.lookup(&5, |v| *v), Some(50));
assert_eq!(tree.lookup(&7, |v| *v), Some(70));
}
#[test]
fn exclusive_iter_insert_updates_existing() {
let tree: Tree<i32, i32> = Tree::new();
tree.insert(5, 50);
{
let mut iter = tree.raw_iter_mut();
let old = iter.insert(5, 500);
assert_eq!(old, Some(50));
}
assert_eq!(tree.lookup(&5, |v| *v), Some(500));
}
#[test]
fn exclusive_iter_remove() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
{
let mut iter = tree.raw_iter_mut();
let removed = iter.remove(&5);
assert_eq!(removed, Some((5, 5)));
}
assert_eq!(tree.lookup(&5, |v| *v), None);
assert_eq!(tree.len(), 9);
}
#[test]
fn exclusive_iter_remove_nonexistent() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
{
let mut iter = tree.raw_iter_mut();
let removed = iter.remove(&100);
assert!(removed.is_none());
}
assert_eq!(tree.len(), 10);
}
#[test]
fn seek_before_first_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 10); }
#[test]
fn seek_after_last_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek(&100);
assert!(iter.next().is_none());
}
#[test]
fn seek_for_prev_before_first_key() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_for_prev(&5);
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 10);
}
#[test]
fn iter_with_string_keys() {
let tree: Tree<String, i32> = Tree::new();
tree.insert("apple".to_string(), 1);
tree.insert("banana".to_string(), 2);
tree.insert("cherry".to_string(), 3);
let mut iter = tree.raw_iter();
iter.seek_to_first();
let (k, _) = iter.next().unwrap();
assert_eq!(k, "apple");
let (k, _) = iter.next().unwrap();
assert_eq!(k, "banana");
let (k, _) = iter.next().unwrap();
assert_eq!(k, "cherry");
assert!(iter.next().is_none());
}
#[test]
fn seek_with_string_borrow() {
let tree: Tree<String, i32> = Tree::new();
tree.insert("apple".to_string(), 1);
tree.insert("banana".to_string(), 2);
tree.insert("cherry".to_string(), 3);
let mut iter = tree.raw_iter();
iter.seek("banana");
let (k, v) = iter.next().unwrap();
assert_eq!(k, "banana");
assert_eq!(*v, 2);
}
#[test]
fn seek_reuses_current_leaf_when_within_bounds() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
iter.seek(&7);
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 7);
}
mod cursor_tests {
use super::super::Cursor;
#[test]
fn cursor_prev_from_after_middle() {
let cursor = Cursor::After(2);
let (pos, new) = cursor.prev_entry().unwrap();
assert_eq!(pos, 2);
assert_eq!(new, Cursor::After(1));
}
#[test]
fn cursor_prev_from_after_one() {
let cursor = Cursor::After(1);
let (pos, new) = cursor.prev_entry().unwrap();
assert_eq!(pos, 1);
assert_eq!(new, Cursor::After(0));
}
#[test]
fn cursor_prev_from_after_zero() {
let cursor = Cursor::After(0);
let (pos, new) = cursor.prev_entry().unwrap();
assert_eq!(pos, 0);
assert_eq!(new, Cursor::Before(0));
}
#[test]
fn cursor_prev_from_before_zero() {
let cursor = Cursor::Before(0);
assert!(cursor.prev_entry().is_none());
}
#[test]
fn cursor_prev_from_before_one() {
let cursor = Cursor::Before(1);
let (pos, new) = cursor.prev_entry().unwrap();
assert_eq!(pos, 0);
assert_eq!(new, Cursor::Before(0));
}
#[test]
fn cursor_prev_from_before_two() {
let cursor = Cursor::Before(2);
let (pos, new) = cursor.prev_entry().unwrap();
assert_eq!(pos, 1);
assert_eq!(new, Cursor::After(0));
}
#[test]
fn cursor_prev_from_before_middle() {
let cursor = Cursor::Before(5);
let (pos, new) = cursor.prev_entry().unwrap();
assert_eq!(pos, 4);
assert_eq!(new, Cursor::After(3));
}
#[test]
fn cursor_next_from_before_start() {
let cursor = Cursor::Before(0);
let (pos, new) = cursor.next_entry(4).unwrap();
assert_eq!(pos, 0);
assert_eq!(new, Cursor::Before(1));
}
#[test]
fn cursor_next_from_before_middle() {
let cursor = Cursor::Before(2);
let (pos, new) = cursor.next_entry(4).unwrap();
assert_eq!(pos, 2);
assert_eq!(new, Cursor::Before(3));
}
#[test]
fn cursor_next_from_before_last() {
let cursor = Cursor::Before(3);
let (pos, new) = cursor.next_entry(4).unwrap();
assert_eq!(pos, 3);
assert_eq!(new, Cursor::Before(4));
}
#[test]
fn cursor_next_from_before_past_end() {
let cursor = Cursor::Before(4);
assert!(cursor.next_entry(4).is_none());
}
#[test]
fn cursor_next_from_after_start() {
let cursor = Cursor::After(0);
let (pos, new) = cursor.next_entry(4).unwrap();
assert_eq!(pos, 1);
assert_eq!(new, Cursor::Before(2));
}
#[test]
fn cursor_next_from_after_middle() {
let cursor = Cursor::After(1);
let (pos, new) = cursor.next_entry(4).unwrap();
assert_eq!(pos, 2);
assert_eq!(new, Cursor::Before(3));
}
#[test]
fn cursor_next_from_after_second_to_last() {
let cursor = Cursor::After(2);
let (pos, new) = cursor.next_entry(4).unwrap();
assert_eq!(pos, 3);
assert_eq!(new, Cursor::Before(4));
}
#[test]
fn cursor_next_from_after_last() {
let cursor = Cursor::After(3);
assert!(cursor.next_entry(4).is_none());
}
#[test]
fn cursor_next_then_prev_returns_same() {
let cursor = Cursor::Before(0);
let (pos1, cursor) = cursor.next_entry(4).unwrap();
assert_eq!(pos1, 0);
assert_eq!(cursor, Cursor::Before(1));
let (pos2, cursor) = cursor.prev_entry().unwrap();
assert_eq!(pos2, 0);
assert_eq!(cursor, Cursor::Before(0));
}
#[test]
fn cursor_prev_then_next_returns_same() {
let cursor = Cursor::After(2);
let (pos1, cursor) = cursor.prev_entry().unwrap();
assert_eq!(pos1, 2);
assert_eq!(cursor, Cursor::After(1));
let (pos2, cursor) = cursor.next_entry(4).unwrap();
assert_eq!(pos2, 2);
assert_eq!(cursor, Cursor::Before(3));
}
#[test]
fn cursor_alternating_next_prev() {
let cursor = Cursor::Before(2);
let (pos, cursor) = cursor.next_entry(5).unwrap();
assert_eq!(pos, 2);
assert_eq!(cursor, Cursor::Before(3));
let (pos, cursor) = cursor.prev_entry().unwrap();
assert_eq!(pos, 2);
assert_eq!(cursor, Cursor::After(1));
let (pos, cursor) = cursor.next_entry(5).unwrap();
assert_eq!(pos, 2);
assert_eq!(cursor, Cursor::Before(3));
let (pos, cursor) = cursor.next_entry(5).unwrap();
assert_eq!(pos, 3);
assert_eq!(cursor, Cursor::Before(4));
let (pos, cursor) = cursor.prev_entry().unwrap();
assert_eq!(pos, 3);
assert_eq!(cursor, Cursor::After(2));
}
}
#[test]
fn bidirectional_next_prev_consistency() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
let (k1, _) = iter.next().unwrap();
assert_eq!(*k1, 5);
let (k2, _) = iter.prev().unwrap();
assert_eq!(*k2, 5);
let (k3, _) = iter.next().unwrap();
assert_eq!(*k3, 5);
let (k4, _) = iter.next().unwrap();
assert_eq!(*k4, 6);
}
#[test]
fn bidirectional_from_start() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..5 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 0);
let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 0);
assert!(iter.prev().is_none());
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 0);
}
#[test]
fn bidirectional_from_end() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..5 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_to_last();
let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 4);
let (k, _) = iter.next().unwrap();
assert_eq!(*k, 4);
assert!(iter.next().is_none());
let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 4);
}
#[test]
fn seek_for_prev_empty_tree() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter();
iter.seek_for_prev(&100);
assert!(iter.prev().is_none());
}
#[test]
fn seek_for_prev_before_all_keys() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_for_prev(&5); assert!(iter.prev().is_none());
}
#[test]
fn seek_for_prev_after_all_keys() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek_for_prev(&100); let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 19); }
#[test]
fn seek_for_prev_middle_gap() {
let tree: Tree<i32, i32> = Tree::new();
tree.insert(10, 1);
tree.insert(20, 2);
tree.insert(40, 4);
tree.insert(50, 5);
let mut iter = tree.raw_iter();
iter.seek_for_prev(&35); let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 20); }
#[test]
fn seek_for_prev_mut_empty_tree() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter_mut();
iter.seek_for_prev(&100);
assert!(iter.prev().is_none());
}
#[test]
fn seek_for_prev_mut_before_all_keys() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter_mut();
iter.seek_for_prev(&5); assert!(iter.prev().is_none());
}
#[test]
fn seek_for_prev_mut_after_all_keys() {
let tree: Tree<i32, i32> = Tree::new();
for i in 10..20 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter_mut();
iter.seek_for_prev(&100); let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 19); }
#[test]
fn seek_for_prev_mut_middle_gap() {
let tree: Tree<i32, i32> = Tree::new();
tree.insert(10, 1);
tree.insert(20, 2);
tree.insert(40, 4);
tree.insert(50, 5);
let mut iter = tree.raw_iter_mut();
iter.seek_for_prev(&35); let (k, _) = iter.prev().unwrap();
assert_eq!(*k, 20); }
#[test]
fn peek_empty_tree() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter();
iter.seek_to_first();
assert!(iter.peek().is_none());
}
#[test]
fn peek_returns_same_as_next() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
let peek_key = iter.peek().map(|(k, v)| (*k, *v));
let next_key = iter.next().map(|(k, v)| (*k, *v));
assert_eq!(peek_key, next_key);
assert_eq!(peek_key.unwrap().0, 0);
}
#[test]
fn peek_does_not_advance() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
assert_eq!(iter.peek(), Some((&0, &0)));
assert_eq!(iter.peek(), Some((&0, &0)));
assert_eq!(iter.peek(), Some((&0, &0)));
assert_eq!(iter.next(), Some((&0, &0)));
assert_eq!(iter.peek(), Some((&1, &10)));
}
#[test]
fn peek_then_next_returns_same() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_first();
for expected in 0..10 {
let peeked = iter.peek().map(|(k, v)| (*k, *v));
let nexted = iter.next().map(|(k, v)| (*k, *v));
assert_eq!(peeked, nexted);
assert_eq!(peeked.unwrap().0, expected);
}
assert!(iter.peek().is_none());
assert!(iter.next().is_none());
}
#[test]
fn peek_at_leaf_boundary() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..200 {
tree.insert(i, i);
}
assert!(tree.height() > 1, "Tree should have multiple levels");
let mut iter = tree.raw_iter();
iter.seek_to_first();
let mut count = 0;
loop {
let peeked = iter.peek().map(|(k, v)| (*k, *v));
if peeked.is_none() {
break;
}
let nexted = iter.next().map(|(k, v)| (*k, *v)).unwrap();
assert_eq!(peeked.unwrap(), nexted);
assert_eq!(nexted.0, count);
count += 1;
}
assert_eq!(count, 200);
}
#[test]
fn peek_from_middle() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
let mut iter = tree.raw_iter();
iter.seek(&5);
assert_eq!(iter.peek(), Some((&5, &5)));
assert_eq!(iter.next(), Some((&5, &5)));
assert_eq!(iter.peek(), Some((&6, &6)));
}
#[test]
fn peek_prev_empty_tree() {
let tree: Tree<i32, i32> = Tree::new();
let mut iter = tree.raw_iter();
iter.seek_to_last();
assert!(iter.peek_prev().is_none());
}
#[test]
fn peek_prev_returns_same_as_prev() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_last();
let peek_result = iter.peek_prev().map(|(k, v)| (*k, *v));
let prev_result = iter.prev().map(|(k, v)| (*k, *v));
assert_eq!(peek_result, prev_result);
assert_eq!(peek_result.unwrap().0, 9);
}
#[test]
fn peek_prev_does_not_advance() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_last();
assert_eq!(iter.peek_prev(), Some((&9, &90)));
assert_eq!(iter.peek_prev(), Some((&9, &90)));
assert_eq!(iter.peek_prev(), Some((&9, &90)));
assert_eq!(iter.prev(), Some((&9, &90)));
assert_eq!(iter.peek_prev(), Some((&8, &80)));
}
#[test]
fn peek_prev_then_prev_returns_same() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter();
iter.seek_to_last();
for expected in (0..10).rev() {
let peeked = iter.peek_prev().map(|(k, v)| (*k, *v));
let preved = iter.prev().map(|(k, v)| (*k, *v));
assert_eq!(peeked, preved);
assert_eq!(peeked.unwrap().0, expected);
}
assert!(iter.peek_prev().is_none());
assert!(iter.prev().is_none());
}
#[test]
fn peek_mut_does_not_advance() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut iter = tree.raw_iter_mut();
iter.seek_to_first();
assert_eq!(*iter.peek().unwrap().0, 0);
assert_eq!(*iter.peek().unwrap().0, 0);
assert_eq!(*iter.next().unwrap().0, 0);
assert_eq!(*iter.peek().unwrap().0, 1);
}
#[test]
fn peek_mut_allows_modification() {
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
{
let mut iter = tree.raw_iter_mut();
iter.seek_to_first();
if let Some((_, v)) = iter.peek() {
*v = 100;
}
}
assert_eq!(tree.lookup(&0, |v| *v), Some(100));
}
#[test]
fn range_peek_within_bounds() {
use std::ops::Bound::Included;
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut range = tree.range(Included(&3), Included(&7));
assert_eq!(range.peek(), Some((&3, &30)));
assert_eq!(range.peek(), Some((&3, &30)));
assert_eq!(range.next(), Some((&3, &30)));
assert_eq!(range.peek(), Some((&4, &40)));
}
#[test]
fn range_peek_respects_upper_bound() {
use std::ops::Bound::{Excluded, Included};
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut range = tree.range(Included(&7), Excluded(&9));
assert_eq!(range.peek(), Some((&7, &70)));
assert_eq!(range.next(), Some((&7, &70)));
assert_eq!(range.peek(), Some((&8, &80)));
assert_eq!(range.next(), Some((&8, &80)));
assert!(range.peek().is_none());
assert!(range.next().is_none());
}
#[test]
fn range_peek_empty_range() {
use std::ops::Bound::{Excluded, Included};
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
let mut range = tree.range(Included(&5), Excluded(&5));
assert!(range.peek().is_none());
}
#[test]
fn range_rev_peek_within_bounds() {
use std::ops::Bound::Included;
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut range = tree.range_rev(Included(&3), Included(&7));
assert_eq!(range.peek(), Some((&7, &70)));
assert_eq!(range.peek(), Some((&7, &70)));
assert_eq!(range.next(), Some((&7, &70)));
assert_eq!(range.peek(), Some((&6, &60)));
}
#[test]
fn range_rev_peek_respects_lower_bound() {
use std::ops::Bound::{Excluded, Included};
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i * 10);
}
let mut range = tree.range_rev(Excluded(&1), Included(&3));
assert_eq!(range.peek(), Some((&3, &30)));
assert_eq!(range.next(), Some((&3, &30)));
assert_eq!(range.peek(), Some((&2, &20)));
assert_eq!(range.next(), Some((&2, &20)));
assert!(range.peek().is_none());
assert!(range.next().is_none());
}
#[test]
fn range_rev_peek_empty_range() {
use std::ops::Bound::{Excluded, Included};
let tree: Tree<i32, i32> = Tree::new();
for i in 0..10 {
tree.insert(i, i);
}
let mut range = tree.range_rev(Excluded(&5), Included(&5));
assert!(range.peek().is_none());
}
mod cursor_peek_tests {
use super::super::Cursor;
#[test]
fn peek_next_pos_before_start() {
let cursor = Cursor::Before(0);
assert_eq!(cursor.peek_next_pos(4), Some(0));
}
#[test]
fn peek_next_pos_before_middle() {
let cursor = Cursor::Before(2);
assert_eq!(cursor.peek_next_pos(4), Some(2));
}
#[test]
fn peek_next_pos_before_end() {
let cursor = Cursor::Before(4);
assert_eq!(cursor.peek_next_pos(4), None);
}
#[test]
fn peek_next_pos_after_start() {
let cursor = Cursor::After(0);
assert_eq!(cursor.peek_next_pos(4), Some(1));
}
#[test]
fn peek_next_pos_after_second_to_last() {
let cursor = Cursor::After(2);
assert_eq!(cursor.peek_next_pos(4), Some(3));
}
#[test]
fn peek_next_pos_after_last() {
let cursor = Cursor::After(3);
assert_eq!(cursor.peek_next_pos(4), None);
}
#[test]
fn peek_prev_pos_after_start() {
let cursor = Cursor::After(0);
assert_eq!(cursor.peek_prev_pos(), Some(0));
}
#[test]
fn peek_prev_pos_after_middle() {
let cursor = Cursor::After(2);
assert_eq!(cursor.peek_prev_pos(), Some(2));
}
#[test]
fn peek_prev_pos_before_start() {
let cursor = Cursor::Before(0);
assert_eq!(cursor.peek_prev_pos(), None);
}
#[test]
fn peek_prev_pos_before_middle() {
let cursor = Cursor::Before(2);
assert_eq!(cursor.peek_prev_pos(), Some(1));
}
}
}