use core::borrow::Borrow;
use core::cell::Cell;
use core::cmp::Ordering;
use core::fmt;
use core::mem;
use core::ptr::NonNull;
use crate::Bound::{self, Excluded, Included, Unbounded};
use crate::link_ops::{self, DefaultLinkOps};
use crate::linked_list::LinkedListOps;
use crate::pointer_ops::PointerOps;
use crate::singly_linked_list::SinglyLinkedListOps;
use crate::unchecked_option::UncheckedOptionExt;
use crate::xor_linked_list::XorLinkedListOps;
use crate::Adapter;
use crate::KeyAdapter;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[allow(missing_docs)]
pub enum Color {
Red,
Black,
}
pub unsafe trait RBTreeOps: link_ops::LinkOps {
unsafe fn left(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr>;
unsafe fn right(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr>;
unsafe fn parent(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr>;
unsafe fn color(&self, ptr: Self::LinkPtr) -> Color;
unsafe fn set_left(&mut self, ptr: Self::LinkPtr, left: Option<Self::LinkPtr>);
unsafe fn set_right(&mut self, ptr: Self::LinkPtr, right: Option<Self::LinkPtr>);
unsafe fn set_parent(&mut self, ptr: Self::LinkPtr, parent: Option<Self::LinkPtr>);
unsafe fn set_color(&mut self, ptr: Self::LinkPtr, color: Color);
}
#[repr(align(2))]
pub struct Link {
left: Cell<Option<NonNull<Link>>>,
right: Cell<Option<NonNull<Link>>>,
parent_color: Cell<usize>,
}
const UNLINKED_MARKER: usize = 0;
impl Link {
#[inline]
pub const fn new() -> Link {
Link {
left: Cell::new(None),
right: Cell::new(None),
parent_color: Cell::new(UNLINKED_MARKER),
}
}
#[inline]
pub fn is_linked(&self) -> bool {
self.parent_color.get() != UNLINKED_MARKER
}
#[inline]
pub unsafe fn force_unlink(&self) {
self.parent_color.set(UNLINKED_MARKER);
}
}
impl DefaultLinkOps for Link {
type Ops = LinkOps;
const NEW: Self::Ops = LinkOps;
}
unsafe impl Send for Link {}
impl Clone for Link {
#[inline]
fn clone(&self) -> Link {
Link::new()
}
}
impl Default for Link {
#[inline]
fn default() -> Link {
Link::new()
}
}
impl fmt::Debug for Link {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_linked() {
write!(f, "linked")
} else {
write!(f, "unlinked")
}
}
}
#[derive(Clone, Copy, Default)]
pub struct LinkOps;
impl LinkOps {
#[inline]
unsafe fn set_parent_color(
self,
ptr: <Self as link_ops::LinkOps>::LinkPtr,
parent: Option<<Self as link_ops::LinkOps>::LinkPtr>,
color: Color,
) {
assert!(mem::align_of::<Link>() >= 2);
let bit = match color {
Color::Red => 0,
Color::Black => 1,
};
let parent_usize = parent.map(|x| x.as_ptr() as usize).unwrap_or(0);
ptr.as_ref().parent_color.set((parent_usize & !1) | bit);
}
}
unsafe impl link_ops::LinkOps for LinkOps {
type LinkPtr = NonNull<Link>;
#[inline]
unsafe fn acquire_link(&mut self, ptr: Self::LinkPtr) -> bool {
if ptr.as_ref().is_linked() {
false
} else {
self.set_parent_color(ptr, None, Color::Black);
true
}
}
#[inline]
unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
ptr.as_ref().parent_color.set(UNLINKED_MARKER);
}
}
unsafe impl RBTreeOps for LinkOps {
#[inline]
unsafe fn left(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
ptr.as_ref().left.get()
}
#[inline]
unsafe fn right(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
ptr.as_ref().right.get()
}
#[inline]
unsafe fn parent(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
let parent_usize = ptr.as_ref().parent_color.get() & !1;
NonNull::new(parent_usize as *mut Link)
}
#[inline]
unsafe fn color(&self, ptr: Self::LinkPtr) -> Color {
if ptr.as_ref().parent_color.get() & 1 == 1 {
Color::Black
} else {
Color::Red
}
}
#[inline]
unsafe fn set_left(&mut self, ptr: Self::LinkPtr, left: Option<Self::LinkPtr>) {
ptr.as_ref().left.set(left);
}
#[inline]
unsafe fn set_right(&mut self, ptr: Self::LinkPtr, right: Option<Self::LinkPtr>) {
ptr.as_ref().right.set(right);
}
#[inline]
unsafe fn set_parent(&mut self, ptr: Self::LinkPtr, parent: Option<Self::LinkPtr>) {
self.set_parent_color(ptr, parent, self.color(ptr));
}
#[inline]
unsafe fn set_color(&mut self, ptr: Self::LinkPtr, color: Color) {
self.set_parent_color(ptr, self.parent(ptr), color);
}
}
unsafe impl SinglyLinkedListOps for LinkOps {
#[inline]
unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
self.right(ptr)
}
#[inline]
unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) {
self.set_right(ptr, next);
}
}
unsafe impl LinkedListOps for LinkOps {
#[inline]
unsafe fn next(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
self.right(ptr)
}
#[inline]
unsafe fn prev(&self, ptr: Self::LinkPtr) -> Option<Self::LinkPtr> {
self.left(ptr)
}
#[inline]
unsafe fn set_next(&mut self, ptr: Self::LinkPtr, next: Option<Self::LinkPtr>) {
self.set_right(ptr, next);
}
#[inline]
unsafe fn set_prev(&mut self, ptr: Self::LinkPtr, prev: Option<Self::LinkPtr>) {
self.set_left(ptr, prev);
}
}
unsafe impl XorLinkedListOps for LinkOps {
#[inline]
unsafe fn next(
&self,
ptr: Self::LinkPtr,
prev: Option<Self::LinkPtr>,
) -> Option<Self::LinkPtr> {
let packed = self.right(ptr).map(|x| x.as_ptr() as usize).unwrap_or(0);
let raw = packed ^ prev.map(|x| x.as_ptr() as usize).unwrap_or(0);
NonNull::new(raw as *mut _)
}
#[inline]
unsafe fn prev(
&self,
ptr: Self::LinkPtr,
next: Option<Self::LinkPtr>,
) -> Option<Self::LinkPtr> {
let packed = self.right(ptr).map(|x| x.as_ptr() as usize).unwrap_or(0);
let raw = packed ^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
NonNull::new(raw as *mut _)
}
#[inline]
unsafe fn set(
&mut self,
ptr: Self::LinkPtr,
prev: Option<Self::LinkPtr>,
next: Option<Self::LinkPtr>,
) {
let new_packed = prev.map(|x| x.as_ptr() as usize).unwrap_or(0)
^ next.map(|x| x.as_ptr() as usize).unwrap_or(0);
let new_next = NonNull::new(new_packed as *mut _);
self.set_right(ptr, new_next);
}
#[inline]
unsafe fn replace_next_or_prev(
&mut self,
ptr: Self::LinkPtr,
old: Option<Self::LinkPtr>,
new: Option<Self::LinkPtr>,
) {
let packed = self.right(ptr).map(|x| x.as_ptr() as usize).unwrap_or(0);
let new_packed = packed
^ old.map(|x| x.as_ptr() as usize).unwrap_or(0)
^ new.map(|x| x.as_ptr() as usize).unwrap_or(0);
let new_next = NonNull::new(new_packed as *mut _);
self.set_right(ptr, new_next);
}
}
#[inline]
unsafe fn is_left_child<T: RBTreeOps>(link_ops: &T, ptr: T::LinkPtr, parent: T::LinkPtr) -> bool {
link_ops.left(parent) == Some(ptr)
}
#[inline]
unsafe fn first_child<T: RBTreeOps>(link_ops: &T, ptr: T::LinkPtr) -> T::LinkPtr {
let mut x = ptr;
while let Some(y) = link_ops.left(x) {
x = y;
}
x
}
#[inline]
unsafe fn last_child<T: RBTreeOps>(link_ops: &T, ptr: T::LinkPtr) -> T::LinkPtr {
let mut x = ptr;
while let Some(y) = link_ops.right(x) {
x = y;
}
x
}
#[inline]
unsafe fn next<T: RBTreeOps>(link_ops: &T, ptr: T::LinkPtr) -> Option<T::LinkPtr> {
if let Some(right) = link_ops.right(ptr) {
Some(first_child(link_ops, right))
} else {
let mut x = ptr;
loop {
if let Some(parent) = link_ops.parent(x) {
if is_left_child(link_ops, x, parent) {
return Some(parent);
}
x = parent;
} else {
return None;
}
}
}
}
#[inline]
unsafe fn prev<T: RBTreeOps>(link_ops: &T, ptr: T::LinkPtr) -> Option<T::LinkPtr> {
if let Some(left) = link_ops.left(ptr) {
Some(last_child(link_ops, left))
} else {
let mut x = ptr;
loop {
if let Some(parent) = link_ops.parent(x) {
if !is_left_child(link_ops, x, parent) {
return Some(parent);
}
x = parent;
} else {
return None;
}
}
}
}
#[inline]
unsafe fn replace_with<T: RBTreeOps>(
link_ops: &mut T,
ptr: T::LinkPtr,
new: T::LinkPtr,
root: &mut Option<T::LinkPtr>,
) {
if let Some(parent) = link_ops.parent(ptr) {
if is_left_child(link_ops, ptr, parent) {
link_ops.set_left(parent, Some(new));
} else {
link_ops.set_right(parent, Some(new));
}
} else {
*root = Some(new);
}
if let Some(left) = link_ops.left(ptr) {
link_ops.set_parent(left, Some(new));
}
if let Some(right) = link_ops.right(ptr) {
link_ops.set_parent(right, Some(new));
}
link_ops.set_left(new, link_ops.left(ptr));
link_ops.set_right(new, link_ops.right(ptr));
link_ops.set_parent(new, link_ops.parent(ptr));
link_ops.set_color(new, link_ops.color(ptr));
link_ops.release_link(ptr);
}
#[inline]
unsafe fn insert_left<T: RBTreeOps>(
link_ops: &mut T,
ptr: T::LinkPtr,
new: T::LinkPtr,
root: &mut Option<T::LinkPtr>,
) {
link_ops.set_parent(new, Some(ptr));
link_ops.set_color(new, Color::Red);
link_ops.set_left(new, None);
link_ops.set_right(new, None);
link_ops.set_left(ptr, Some(new));
post_insert(link_ops, new, root);
}
#[inline]
unsafe fn insert_right<T: RBTreeOps>(
link_ops: &mut T,
ptr: T::LinkPtr,
new: T::LinkPtr,
root: &mut Option<T::LinkPtr>,
) {
link_ops.set_parent(new, Some(ptr));
link_ops.set_color(new, Color::Red);
link_ops.set_left(new, None);
link_ops.set_right(new, None);
link_ops.set_right(ptr, Some(new));
post_insert(link_ops, new, root);
}
unsafe fn rotate_left<T: RBTreeOps>(
link_ops: &mut T,
ptr: T::LinkPtr,
root: &mut Option<T::LinkPtr>,
) {
let y = link_ops.right(ptr).unwrap_unchecked();
link_ops.set_right(ptr, link_ops.left(y));
if let Some(right) = link_ops.right(ptr) {
link_ops.set_parent(right, Some(ptr));
}
link_ops.set_parent(y, link_ops.parent(ptr));
if let Some(parent) = link_ops.parent(ptr) {
if is_left_child(link_ops, ptr, parent) {
link_ops.set_left(parent, Some(y));
} else {
link_ops.set_right(parent, Some(y));
}
} else {
*root = Some(y);
}
link_ops.set_left(y, Some(ptr));
link_ops.set_parent(ptr, Some(y));
}
unsafe fn rotate_right<T: RBTreeOps>(
link_ops: &mut T,
ptr: T::LinkPtr,
root: &mut Option<T::LinkPtr>,
) {
let y = link_ops.left(ptr).unwrap_unchecked();
link_ops.set_left(ptr, link_ops.right(y));
if let Some(left) = link_ops.left(ptr) {
link_ops.set_parent(left, Some(ptr));
}
link_ops.set_parent(y, link_ops.parent(ptr));
if let Some(parent) = link_ops.parent(ptr) {
if is_left_child(link_ops, ptr, parent) {
link_ops.set_left(parent, Some(y));
} else {
link_ops.set_right(parent, Some(y));
}
} else {
*root = Some(y);
}
link_ops.set_right(y, Some(ptr));
link_ops.set_parent(ptr, Some(y));
}
unsafe fn post_insert<T: RBTreeOps>(
link_ops: &mut T,
ptr: T::LinkPtr,
root: &mut Option<T::LinkPtr>,
) {
let mut x = ptr;
while let Some(parent) = link_ops.parent(x) {
if link_ops.color(parent) != Color::Red {
break;
}
let grandparent = link_ops.parent(parent).unwrap_unchecked();
if is_left_child(link_ops, parent, grandparent) {
let y = link_ops.right(grandparent);
if let Some(y) = y {
if link_ops.color(y) == Color::Red {
x = parent;
link_ops.set_color(x, Color::Black);
x = grandparent;
if link_ops.parent(x).is_none() {
link_ops.set_color(x, Color::Black);
} else {
link_ops.set_color(x, Color::Red);
}
link_ops.set_color(y, Color::Black);
continue;
}
}
if !is_left_child(link_ops, x, parent) {
x = parent;
rotate_left(link_ops, x, root);
}
x = link_ops.parent(x).unwrap_unchecked();
link_ops.set_color(x, Color::Black);
x = link_ops.parent(x).unwrap_unchecked();
link_ops.set_color(x, Color::Red);
rotate_right(link_ops, x, root);
break;
} else {
let y = link_ops.left(grandparent);
if let Some(y) = y {
if link_ops.color(y) == Color::Red {
x = parent;
link_ops.set_color(x, Color::Black);
x = grandparent;
if link_ops.parent(x).is_none() {
link_ops.set_color(x, Color::Black);
} else {
link_ops.set_color(x, Color::Red);
}
link_ops.set_color(y, Color::Black);
continue;
}
}
if is_left_child(link_ops, x, parent) {
x = parent;
rotate_right(link_ops, x, root);
}
x = link_ops.parent(x).unwrap_unchecked();
link_ops.set_color(x, Color::Black);
x = link_ops.parent(x).unwrap_unchecked();
link_ops.set_color(x, Color::Red);
rotate_left(link_ops, x, root);
break;
}
}
}
unsafe fn remove<T: RBTreeOps>(link_ops: &mut T, ptr: T::LinkPtr, root: &mut Option<T::LinkPtr>) {
let y = if link_ops.left(ptr).is_none() || link_ops.right(ptr).is_none() {
ptr
} else {
next(link_ops, ptr).unwrap_unchecked()
};
let x = if link_ops.left(y).is_some() {
link_ops.left(y)
} else {
link_ops.right(y)
};
let mut w = None;
if let Some(x) = x {
link_ops.set_parent(x, link_ops.parent(y));
}
if let Some(y_parent) = link_ops.parent(y) {
if is_left_child(link_ops, y, y_parent) {
link_ops.set_left(y_parent, x);
w = link_ops.right(y_parent);
} else {
link_ops.set_right(y_parent, x);
w = link_ops.left(y_parent);
}
} else {
*root = x;
}
let removed_black = link_ops.color(y) == Color::Black;
if y != ptr {
if let Some(parent) = link_ops.parent(ptr) {
link_ops.set_parent(y, Some(parent));
if is_left_child(link_ops, ptr, parent) {
link_ops.set_left(parent, Some(y));
} else {
link_ops.set_right(parent, Some(y));
}
} else {
link_ops.set_parent(y, None);
*root = Some(y);
}
link_ops.set_left(y, link_ops.left(ptr));
link_ops.set_parent(link_ops.left(y).unwrap_unchecked(), Some(y));
link_ops.set_right(y, link_ops.right(ptr));
if let Some(y_right) = link_ops.right(y) {
link_ops.set_parent(y_right, Some(y));
}
link_ops.set_color(y, link_ops.color(ptr));
}
if removed_black && !root.is_none() {
if let Some(x) = x {
link_ops.set_color(x, Color::Black);
} else {
let mut w = w.unwrap_unchecked();
loop {
let mut w_parent = link_ops.parent(w).unwrap_unchecked();
if !is_left_child(link_ops, w, w_parent) {
if link_ops.color(w) == Color::Red {
link_ops.set_color(w, Color::Black);
link_ops.set_color(w_parent, Color::Red);
rotate_left(link_ops, w_parent, root);
w = link_ops
.right(link_ops.left(w).unwrap_unchecked())
.unwrap_unchecked();
w_parent = link_ops.parent(w).unwrap_unchecked();
}
let left_color = link_ops.left(w).map(|x| link_ops.color(x));
let right_color = link_ops.right(w).map(|x| link_ops.color(x));
if (left_color != Some(Color::Red)) && (right_color != Some(Color::Red)) {
link_ops.set_color(w, Color::Red);
if link_ops.parent(w_parent).is_none()
|| link_ops.color(w_parent) == Color::Red
{
link_ops.set_color(w_parent, Color::Black);
break;
}
let w_grandparent = link_ops.parent(w_parent).unwrap_unchecked();
w = if is_left_child(link_ops, w_parent, w_grandparent) {
link_ops.right(w_grandparent).unwrap_unchecked()
} else {
link_ops.left(w_grandparent).unwrap_unchecked()
};
} else {
if link_ops.right(w).map(|x| link_ops.color(x)) != Some(Color::Red) {
link_ops.set_color(link_ops.left(w).unwrap_unchecked(), Color::Black);
link_ops.set_color(w, Color::Red);
rotate_right(link_ops, w, root);
w = link_ops.parent(w).unwrap_unchecked();
w_parent = link_ops.parent(w).unwrap_unchecked();
}
link_ops.set_color(w, link_ops.color(w_parent));
link_ops.set_color(w_parent, Color::Black);
link_ops.set_color(link_ops.right(w).unwrap_unchecked(), Color::Black);
rotate_left(link_ops, w_parent, root);
break;
}
} else {
if link_ops.color(w) == Color::Red {
link_ops.set_color(w, Color::Black);
link_ops.set_color(w_parent, Color::Red);
rotate_right(link_ops, w_parent, root);
w = link_ops
.left(link_ops.right(w).unwrap_unchecked())
.unwrap_unchecked();
w_parent = link_ops.parent(w).unwrap_unchecked();
}
let left_color = link_ops.left(w).map(|x| link_ops.color(x));
let right_color = link_ops.right(w).map(|x| link_ops.color(x));
if (left_color != Some(Color::Red)) && (right_color != Some(Color::Red)) {
link_ops.set_color(w, Color::Red);
if link_ops.parent(w_parent).is_none()
|| link_ops.color(w_parent) == Color::Red
{
link_ops.set_color(w_parent, Color::Black);
break;
}
w = if is_left_child(
link_ops,
w_parent,
link_ops.parent(w_parent).unwrap_unchecked(),
) {
link_ops
.right(link_ops.parent(w_parent).unwrap_unchecked())
.unwrap_unchecked()
} else {
link_ops
.left(link_ops.parent(w_parent).unwrap_unchecked())
.unwrap_unchecked()
};
} else {
if link_ops.left(w).map(|x| link_ops.color(x)) != Some(Color::Red) {
link_ops.set_color(link_ops.right(w).unwrap_unchecked(), Color::Black);
link_ops.set_color(w, Color::Red);
rotate_left(link_ops, w, root);
w = link_ops.parent(w).unwrap_unchecked();
w_parent = link_ops.parent(w).unwrap_unchecked();
}
link_ops.set_color(w, link_ops.color(w_parent));
link_ops.set_color(w_parent, Color::Black);
link_ops.set_color(link_ops.left(w).unwrap_unchecked(), Color::Black);
rotate_right(link_ops, w_parent, root);
break;
}
}
}
}
}
link_ops.release_link(ptr);
}
pub struct Cursor<'a, A: Adapter>
where
A::LinkOps: RBTreeOps,
{
current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
tree: &'a RBTree<A>,
}
impl<'a, A: Adapter> Clone for Cursor<'a, A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
fn clone(&self) -> Cursor<'a, A> {
Cursor {
current: self.current,
tree: self.tree,
}
}
}
impl<'a, A: Adapter> Cursor<'a, A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
pub fn is_null(&self) -> bool {
self.current.is_none()
}
#[inline]
pub fn get(&self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
Some(unsafe { &*self.tree.adapter.get_value(self.current?) })
}
#[inline]
pub fn clone_pointer(&self) -> Option<<A::PointerOps as PointerOps>::Pointer>
where
<A::PointerOps as PointerOps>::Pointer: Clone,
{
let raw_pointer = self.get()? as *const <A::PointerOps as PointerOps>::Value;
Some(unsafe {
crate::pointer_ops::clone_pointer_from_raw(self.tree.adapter.pointer_ops(), raw_pointer)
})
}
#[inline]
pub fn move_next(&mut self) {
if let Some(current) = self.current {
self.current = unsafe { next(self.tree.adapter.link_ops(), current) };
} else if let Some(root) = self.tree.root {
self.current = Some(unsafe { first_child(self.tree.adapter.link_ops(), root) });
} else {
self.current = None;
}
}
#[inline]
pub fn move_prev(&mut self) {
if let Some(current) = self.current {
self.current = unsafe { prev(self.tree.adapter.link_ops(), current) };
} else if let Some(root) = self.tree.root {
self.current = Some(unsafe { last_child(self.tree.adapter.link_ops(), root) });
} else {
self.current = None;
}
}
#[inline]
pub fn peek_next(&self) -> Cursor<'_, A> {
let mut next = self.clone();
next.move_next();
next
}
#[inline]
pub fn peek_prev(&self) -> Cursor<'_, A> {
let mut prev = self.clone();
prev.move_prev();
prev
}
}
pub struct CursorMut<'a, A: Adapter>
where
A::LinkOps: RBTreeOps,
{
current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
tree: &'a mut RBTree<A>,
}
impl<'a, A: Adapter> CursorMut<'a, A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
pub fn is_null(&self) -> bool {
self.current.is_none()
}
#[inline]
pub fn get(&self) -> Option<&<A::PointerOps as PointerOps>::Value> {
Some(unsafe { &*self.tree.adapter.get_value(self.current?) })
}
#[inline]
pub fn as_cursor(&self) -> Cursor<'_, A> {
Cursor {
current: self.current,
tree: self.tree,
}
}
#[inline]
pub fn move_next(&mut self) {
if let Some(current) = self.current {
self.current = unsafe { next(self.tree.adapter.link_ops(), current) };
} else if let Some(root) = self.tree.root {
self.current = Some(unsafe { first_child(self.tree.adapter.link_ops(), root) });
} else {
self.current = None;
}
}
#[inline]
pub fn move_prev(&mut self) {
if let Some(current) = self.current {
self.current = unsafe { prev(self.tree.adapter.link_ops(), current) };
} else if let Some(root) = self.tree.root {
self.current = Some(unsafe { last_child(self.tree.adapter.link_ops(), root) });
} else {
self.current = None;
}
}
#[inline]
pub fn peek_next(&self) -> Cursor<'_, A> {
let mut next = self.as_cursor();
next.move_next();
next
}
#[inline]
pub fn peek_prev(&self) -> Cursor<'_, A> {
let mut prev = self.as_cursor();
prev.move_prev();
prev
}
#[inline]
pub fn remove(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
unsafe {
if let Some(current) = self.current {
let next = next(self.tree.adapter.link_ops(), current);
let result = current;
remove(
self.tree.adapter.link_ops_mut(),
current,
&mut self.tree.root,
);
self.current = next;
Some(
self.tree
.adapter
.pointer_ops()
.from_raw(self.tree.adapter.get_value(result)),
)
} else {
None
}
}
}
#[inline]
pub fn replace_with(
&mut self,
val: <A::PointerOps as PointerOps>::Pointer,
) -> Result<<A::PointerOps as PointerOps>::Pointer, <A::PointerOps as PointerOps>::Pointer>
{
unsafe {
if let Some(current) = self.current {
let new = self.tree.node_from_value(val);
let result = current;
replace_with(
self.tree.adapter.link_ops_mut(),
current,
new,
&mut self.tree.root,
);
self.current = Some(new);
Ok(self
.tree
.adapter
.pointer_ops()
.from_raw(self.tree.adapter.get_value(result)))
} else {
Err(val)
}
}
}
#[inline]
pub fn insert_after(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
unsafe {
let new = self.tree.node_from_value(val);
let link_ops = self.tree.adapter.link_ops_mut();
if let Some(root) = self.tree.root {
if let Some(current) = self.current {
if link_ops.right(current).is_some() {
let next = next(link_ops, current).unwrap_unchecked();
insert_left(link_ops, next, new, &mut self.tree.root);
} else {
insert_right(link_ops, current, new, &mut self.tree.root);
}
} else {
insert_left(
link_ops,
first_child(link_ops, root),
new,
&mut self.tree.root,
);
}
} else {
self.tree.insert_root(new);
}
}
}
#[inline]
pub fn insert_before(&mut self, val: <A::PointerOps as PointerOps>::Pointer) {
unsafe {
let new = self.tree.node_from_value(val);
let link_ops = self.tree.adapter.link_ops_mut();
if let Some(root) = self.tree.root {
if let Some(current) = self.current {
if link_ops.left(current).is_some() {
let prev = prev(link_ops, current).unwrap_unchecked();
insert_right(link_ops, prev, new, &mut self.tree.root);
} else {
insert_left(link_ops, current, new, &mut self.tree.root);
}
} else {
insert_right(
link_ops,
last_child(link_ops, root),
new,
&mut self.tree.root,
);
}
} else {
self.tree.insert_root(new);
}
}
}
}
impl<'a, A: for<'b> KeyAdapter<'b>> CursorMut<'a, A>
where
<A as Adapter>::LinkOps: RBTreeOps,
{
#[inline]
pub fn insert<'c>(&'c mut self, val: <A::PointerOps as PointerOps>::Pointer)
where
<A as KeyAdapter<'c>>::Key: Ord,
{
self.tree.insert(val);
}
}
pub struct RBTree<A: Adapter>
where
A::LinkOps: RBTreeOps,
{
root: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
adapter: A,
}
impl<A: Adapter> RBTree<A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
fn node_from_value(
&mut self,
val: <A::PointerOps as PointerOps>::Pointer,
) -> <A::LinkOps as link_ops::LinkOps>::LinkPtr {
use link_ops::LinkOps;
unsafe {
let raw = self.adapter.pointer_ops().into_raw(val);
let link = self.adapter.get_link(raw);
if !self.adapter.link_ops_mut().acquire_link(link) {
self.adapter.pointer_ops().from_raw(raw);
panic!("attempted to insert an object that is already linked");
}
link
}
}
#[cfg(not(feature = "nightly"))]
#[inline]
pub fn new(adapter: A) -> RBTree<A> {
RBTree {
root: None,
adapter,
}
}
#[cfg(feature = "nightly")]
#[inline]
pub const fn new(adapter: A) -> RBTree<A> {
RBTree {
root: None,
adapter,
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.root.is_none()
}
#[inline]
pub fn cursor(&self) -> Cursor<'_, A> {
Cursor {
current: None,
tree: self,
}
}
#[inline]
pub fn cursor_mut(&mut self) -> CursorMut<'_, A> {
CursorMut {
current: None,
tree: self,
}
}
#[inline]
pub unsafe fn cursor_from_ptr(
&self,
ptr: *const <A::PointerOps as PointerOps>::Value,
) -> Cursor<'_, A> {
Cursor {
current: Some(self.adapter.get_link(ptr)),
tree: self,
}
}
#[inline]
pub unsafe fn cursor_mut_from_ptr(
&mut self,
ptr: *const <A::PointerOps as PointerOps>::Value,
) -> CursorMut<'_, A> {
CursorMut {
current: Some(self.adapter.get_link(ptr)),
tree: self,
}
}
#[inline]
pub fn front(&self) -> Cursor<'_, A> {
let mut cursor = self.cursor();
cursor.move_next();
cursor
}
#[inline]
pub fn front_mut(&mut self) -> CursorMut<'_, A> {
let mut cursor = self.cursor_mut();
cursor.move_next();
cursor
}
#[inline]
pub fn back(&self) -> Cursor<'_, A> {
let mut cursor = self.cursor();
cursor.move_prev();
cursor
}
#[inline]
pub fn back_mut(&mut self) -> CursorMut<'_, A> {
let mut cursor = self.cursor_mut();
cursor.move_prev();
cursor
}
#[inline]
unsafe fn insert_root(&mut self, node: <A::LinkOps as link_ops::LinkOps>::LinkPtr) {
self.adapter.link_ops_mut().set_parent(node, None);
self.adapter.link_ops_mut().set_color(node, Color::Black);
self.adapter.link_ops_mut().set_left(node, None);
self.adapter.link_ops_mut().set_right(node, None);
self.root = Some(node);
}
#[inline]
pub fn iter(&self) -> Iter<'_, A> {
let link_ops = self.adapter.link_ops();
if let Some(root) = self.root {
Iter {
head: Some(unsafe { first_child(link_ops, root) }),
tail: Some(unsafe { last_child(link_ops, root) }),
tree: self,
}
} else {
Iter {
head: None,
tail: None,
tree: self,
}
}
}
#[inline]
fn clear_recurse(&mut self, current: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>) {
use link_ops::LinkOps;
if let Some(current) = current {
unsafe {
let left = self.adapter.link_ops_mut().left(current);
let right = self.adapter.link_ops_mut().right(current);
self.clear_recurse(left);
self.clear_recurse(right);
self.adapter.link_ops_mut().release_link(current);
self.adapter
.pointer_ops()
.from_raw(self.adapter.get_value(current));
}
}
}
#[inline]
pub fn clear(&mut self) {
let root = self.root.take();
self.clear_recurse(root);
}
#[inline]
pub fn fast_clear(&mut self) {
self.root = None;
}
#[inline]
pub fn take(&mut self) -> RBTree<A>
where
A: Clone,
{
let tree = RBTree {
root: self.root,
adapter: self.adapter.clone(),
};
self.root = None;
tree
}
}
impl<A: for<'a> KeyAdapter<'a>> RBTree<A>
where
<A as Adapter>::LinkOps: RBTreeOps,
{
#[inline]
fn find_internal<'a, Q: ?Sized + Ord>(
&self,
key: &Q,
) -> Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
<A::PointerOps as PointerOps>::Value: 'a,
{
let link_ops = self.adapter.link_ops();
let mut tree = self.root;
while let Some(x) = tree {
let current = unsafe { &*self.adapter.get_value(x) };
match key.cmp(self.adapter.get_key(current).borrow()) {
Ordering::Less => tree = unsafe { link_ops.left(x) },
Ordering::Equal => return tree,
Ordering::Greater => tree = unsafe { link_ops.right(x) },
}
}
None
}
#[inline]
pub fn find<'a, Q: ?Sized + Ord>(&'a self, key: &Q) -> Cursor<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
Cursor {
current: self.find_internal(key),
tree: self,
}
}
#[inline]
pub fn find_mut<'a, Q: ?Sized + Ord>(&'a mut self, key: &Q) -> CursorMut<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
CursorMut {
current: self.find_internal(key),
tree: self,
}
}
#[inline]
fn lower_bound_internal<'a, Q: ?Sized + Ord>(
&self,
bound: Bound<&Q>,
) -> Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
<A::PointerOps as PointerOps>::Value: 'a,
{
let link_ops = self.adapter.link_ops();
let mut tree = self.root;
let mut result = None;
while let Some(x) = tree {
let current = unsafe { &*self.adapter.get_value(x) };
let cond = match bound {
Unbounded => true,
Included(key) => key <= self.adapter.get_key(current).borrow(),
Excluded(key) => key < self.adapter.get_key(current).borrow(),
};
if cond {
result = tree;
tree = unsafe { link_ops.left(x) };
} else {
tree = unsafe { link_ops.right(x) };
}
}
result
}
#[inline]
pub fn lower_bound<'a, Q: ?Sized + Ord>(&'a self, bound: Bound<&Q>) -> Cursor<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
Cursor {
current: self.lower_bound_internal(bound),
tree: self,
}
}
#[inline]
pub fn lower_bound_mut<'a, Q: ?Sized + Ord>(&'a mut self, bound: Bound<&Q>) -> CursorMut<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
CursorMut {
current: self.lower_bound_internal(bound),
tree: self,
}
}
#[inline]
fn upper_bound_internal<'a, Q: ?Sized + Ord>(
&self,
bound: Bound<&Q>,
) -> Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
<A::PointerOps as PointerOps>::Value: 'a,
{
let link_ops = self.adapter.link_ops();
let mut tree = self.root;
let mut result = None;
while let Some(x) = tree {
let current = unsafe { &*self.adapter.get_value(x) };
let cond = match bound {
Unbounded => false,
Included(key) => key < self.adapter.get_key(current).borrow(),
Excluded(key) => key <= self.adapter.get_key(current).borrow(),
};
if cond {
tree = unsafe { link_ops.left(x) };
} else {
result = tree;
tree = unsafe { link_ops.right(x) };
}
}
result
}
#[inline]
pub fn upper_bound<'a, Q: ?Sized + Ord>(&'a self, bound: Bound<&Q>) -> Cursor<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
Cursor {
current: self.upper_bound_internal(bound),
tree: self,
}
}
#[inline]
pub fn upper_bound_mut<'a, Q: ?Sized + Ord>(&'a mut self, bound: Bound<&Q>) -> CursorMut<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
CursorMut {
current: self.upper_bound_internal(bound),
tree: self,
}
}
#[inline]
pub fn insert<'a>(&'a mut self, val: <A::PointerOps as PointerOps>::Pointer) -> CursorMut<'_, A>
where
<A as KeyAdapter<'a>>::Key: Ord,
{
unsafe {
let new = self.node_from_value(val);
let raw = self.adapter.get_value(new);
if let Some(root) = self.root {
let key = self.adapter.get_key(&*raw);
let mut tree = root;
loop {
let current = &*self.adapter.get_value(tree);
if key < self.adapter.get_key(current) {
if let Some(left) = self.adapter.link_ops().left(tree) {
tree = left;
} else {
insert_left(self.adapter.link_ops_mut(), tree, new, &mut self.root);
break;
}
} else {
if let Some(right) = self.adapter.link_ops().right(tree) {
tree = right;
} else {
insert_right(self.adapter.link_ops_mut(), tree, new, &mut self.root);
break;
}
}
}
} else {
self.insert_root(new);
}
CursorMut {
current: Some(new),
tree: self,
}
}
}
#[inline]
pub fn entry<'a, Q: ?Sized + Ord>(&'a mut self, key: &Q) -> Entry<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Q>,
{
unsafe {
if let Some(root) = self.root {
let mut tree = root;
loop {
let current = &*self.adapter.get_value(tree);
match key.cmp(self.adapter.get_key(current).borrow()) {
Ordering::Less => {
if let Some(left) = self.adapter.link_ops().left(tree) {
tree = left;
} else {
return Entry::Vacant(InsertCursor {
parent: Some(tree),
insert_left: true,
tree: self,
});
}
}
Ordering::Equal => {
return Entry::Occupied(CursorMut {
current: Some(tree),
tree: self,
});
}
Ordering::Greater => {
if let Some(right) = self.adapter.link_ops().right(tree) {
tree = right;
} else {
return Entry::Vacant(InsertCursor {
parent: Some(tree),
insert_left: false,
tree: self,
});
}
}
}
}
} else {
Entry::Vacant(InsertCursor {
parent: None,
insert_left: false,
tree: self,
})
}
}
}
#[inline]
pub fn range<'a, Min: ?Sized + Ord, Max: ?Sized + Ord>(
&'a self,
min: Bound<&Min>,
max: Bound<&Max>,
) -> Iter<'a, A>
where
<A as KeyAdapter<'a>>::Key: Borrow<Min> + Borrow<Max>,
<A as KeyAdapter<'a>>::Key: Ord,
{
let lower = self.lower_bound_internal(min);
let upper = self.upper_bound_internal(max);
if let (Some(lower), Some(upper)) = (lower, upper) {
let lower_key = unsafe { self.adapter.get_key(&*self.adapter.get_value(lower)) };
let upper_key = unsafe { self.adapter.get_key(&*self.adapter.get_value(upper)) };
if upper_key >= lower_key {
return Iter {
head: Some(lower),
tail: Some(upper),
tree: self,
};
}
}
Iter {
head: None,
tail: None,
tree: self,
}
}
}
unsafe impl<A: Adapter + Sync> Sync for RBTree<A>
where
<A::PointerOps as PointerOps>::Value: Sync,
A::LinkOps: RBTreeOps,
{
}
unsafe impl<A: Adapter + Send> Send for RBTree<A>
where
<A::PointerOps as PointerOps>::Pointer: Send,
A::LinkOps: RBTreeOps,
{
}
impl<A: Adapter> Drop for RBTree<A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
fn drop(&mut self) {
self.clear();
}
}
impl<A: Adapter> IntoIterator for RBTree<A>
where
A::LinkOps: RBTreeOps,
{
type Item = <A::PointerOps as PointerOps>::Pointer;
type IntoIter = IntoIter<A>;
#[inline]
fn into_iter(self) -> IntoIter<A> {
let link_ops = self.adapter.link_ops();
if let Some(root) = self.root {
IntoIter {
head: Some(unsafe { first_child(link_ops, root) }),
tail: Some(unsafe { last_child(link_ops, root) }),
tree: self,
}
} else {
IntoIter {
head: None,
tail: None,
tree: self,
}
}
}
}
impl<'a, A: Adapter + 'a> IntoIterator for &'a RBTree<A>
where
A::LinkOps: RBTreeOps,
{
type Item = &'a <A::PointerOps as PointerOps>::Value;
type IntoIter = Iter<'a, A>;
#[inline]
fn into_iter(self) -> Iter<'a, A> {
self.iter()
}
}
impl<A: Adapter + Default> Default for RBTree<A>
where
A::LinkOps: RBTreeOps,
{
fn default() -> RBTree<A> {
RBTree::new(A::default())
}
}
impl<A: Adapter> fmt::Debug for RBTree<A>
where
A::LinkOps: RBTreeOps,
<A::PointerOps as PointerOps>::Value: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
pub struct InsertCursor<'a, A: Adapter>
where
A::LinkOps: RBTreeOps,
{
parent: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
insert_left: bool,
tree: &'a mut RBTree<A>,
}
impl<'a, A: Adapter + 'a> InsertCursor<'a, A>
where
A::LinkOps: RBTreeOps,
{
pub fn insert(self, val: <A::PointerOps as PointerOps>::Pointer) -> CursorMut<'a, A> {
unsafe {
let new = self.tree.node_from_value(val);
let link_ops = self.tree.adapter.link_ops_mut();
if let Some(parent) = self.parent {
if self.insert_left {
insert_left(link_ops, parent, new, &mut self.tree.root);
} else {
insert_right(link_ops, parent, new, &mut self.tree.root);
}
} else {
self.tree.insert_root(new);
}
CursorMut {
current: Some(new),
tree: self.tree,
}
}
}
}
pub enum Entry<'a, A: Adapter>
where
A::LinkOps: RBTreeOps,
{
Occupied(CursorMut<'a, A>),
Vacant(InsertCursor<'a, A>),
}
impl<'a, A: Adapter + 'a> Entry<'a, A>
where
A::LinkOps: RBTreeOps,
{
pub fn or_insert(self, val: <A::PointerOps as PointerOps>::Pointer) -> CursorMut<'a, A> {
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert(val),
}
}
pub fn or_insert_with<F>(self, default: F) -> CursorMut<'a, A>
where
F: FnOnce() -> <A::PointerOps as PointerOps>::Pointer,
{
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert(default()),
}
}
}
pub struct Iter<'a, A: Adapter>
where
A::LinkOps: RBTreeOps,
{
head: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
tail: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
tree: &'a RBTree<A>,
}
impl<'a, A: Adapter + 'a> Iterator for Iter<'a, A>
where
A::LinkOps: RBTreeOps,
{
type Item = &'a <A::PointerOps as PointerOps>::Value;
#[inline]
fn next(&mut self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
let head = self.head?;
if Some(head) == self.tail {
self.head = None;
self.tail = None;
} else {
self.head = unsafe { next(self.tree.adapter.link_ops(), head) };
}
Some(unsafe { &*self.tree.adapter.get_value(head) })
}
}
impl<'a, A: Adapter + 'a> DoubleEndedIterator for Iter<'a, A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
fn next_back(&mut self) -> Option<&'a <A::PointerOps as PointerOps>::Value> {
let tail = self.tail?;
if Some(tail) == self.head {
self.head = None;
self.tail = None;
} else {
self.tail = unsafe { prev(self.tree.adapter.link_ops(), tail) };
}
Some(unsafe { &*self.tree.adapter.get_value(tail) })
}
}
impl<'a, A: Adapter + 'a> Clone for Iter<'a, A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
fn clone(&self) -> Iter<'a, A> {
Iter {
head: self.head,
tail: self.tail,
tree: self.tree,
}
}
}
pub struct IntoIter<A: Adapter>
where
A::LinkOps: RBTreeOps,
{
head: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
tail: Option<<A::LinkOps as link_ops::LinkOps>::LinkPtr>,
tree: RBTree<A>,
}
impl<A: Adapter> Iterator for IntoIter<A>
where
A::LinkOps: RBTreeOps,
{
type Item = <A::PointerOps as PointerOps>::Pointer;
#[inline]
fn next(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
use link_ops::LinkOps;
let head = self.head?;
let link_ops = self.tree.adapter.link_ops_mut();
unsafe {
if let Some(parent) = link_ops.parent(head) {
link_ops.set_left(parent, link_ops.right(head));
} else {
self.tree.root = link_ops.right(head);
if link_ops.right(head).is_none() {
self.tail = None;
}
}
if let Some(right) = link_ops.right(head) {
link_ops.set_parent(right, link_ops.parent(head));
self.head = Some(first_child(link_ops, right));
} else {
self.head = link_ops.parent(head);
}
link_ops.release_link(head);
Some(
self.tree
.adapter
.pointer_ops()
.from_raw(self.tree.adapter.get_value(head)),
)
}
}
}
impl<A: Adapter> DoubleEndedIterator for IntoIter<A>
where
A::LinkOps: RBTreeOps,
{
#[inline]
fn next_back(&mut self) -> Option<<A::PointerOps as PointerOps>::Pointer> {
use link_ops::LinkOps;
let tail = self.tail?;
let link_ops = self.tree.adapter.link_ops_mut();
unsafe {
if let Some(parent) = link_ops.parent(tail) {
link_ops.set_right(parent, link_ops.left(tail));
} else {
self.tree.root = link_ops.left(tail);
if link_ops.left(tail).is_none() {
self.tail = None;
}
}
if let Some(left) = link_ops.left(tail) {
link_ops.set_parent(left, link_ops.parent(tail));
self.tail = Some(last_child(link_ops, left));
} else {
self.tail = link_ops.parent(tail);
}
link_ops.release_link(tail);
Some(
self.tree
.adapter
.pointer_ops()
.from_raw(self.tree.adapter.get_value(tail)),
)
}
}
}
#[cfg(test)]
mod tests {
use super::{Entry, KeyAdapter, Link, PointerOps, RBTree};
use crate::Bound::*;
use rand::prelude::*;
use rand_xorshift::XorShiftRng;
use std::fmt;
use std::rc::Rc;
use std::vec::Vec;
use std::{format, vec};
#[derive(Clone)]
struct Obj {
link: Link,
value: i32,
}
impl fmt::Debug for Obj {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value)
}
}
intrusive_adapter!(ObjAdapter = Rc<Obj>: Obj { link: Link });
impl<'a> KeyAdapter<'a> for ObjAdapter {
type Key = i32;
fn get_key(&self, value: &'a <Self::PointerOps as PointerOps>::Value) -> i32 {
value.value
}
}
fn make_obj(value: i32) -> Rc<Obj> {
Rc::new(Obj {
link: Link::new(),
value,
})
}
#[test]
fn test_link() {
let a = make_obj(1);
assert!(!a.link.is_linked());
assert_eq!(format!("{:?}", a.link), "unlinked");
let mut b = RBTree::<ObjAdapter>::default();
assert!(b.is_empty());
assert_eq!(b.insert(a.clone()).get().unwrap().value, 1);
assert!(!b.is_empty());
assert!(a.link.is_linked());
assert_eq!(format!("{:?}", a.link), "linked");
let c = a.as_ref().clone();
assert!(!c.link.is_linked());
unsafe {
assert_eq!(b.cursor_from_ptr(a.as_ref()).get().unwrap().value, 1);
assert_eq!(b.cursor_mut_from_ptr(a.as_ref()).get().unwrap().value, 1);
}
assert_eq!(
b.front_mut().remove().unwrap().as_ref() as *const _,
a.as_ref() as *const _
);
assert!(b.is_empty());
assert!(!a.link.is_linked());
}
#[test]
fn test_cursor() {
let a = make_obj(1);
let b = make_obj(2);
let c = make_obj(3);
let mut t = RBTree::new(ObjAdapter::new());
let mut cur = t.cursor_mut();
assert!(cur.is_null());
assert!(cur.get().is_none());
assert!(cur.remove().is_none());
cur.insert_before(a.clone());
cur.insert_before(c.clone());
cur.move_prev();
cur.insert(b.clone());
assert!(cur.peek_next().is_null());
cur.move_next();
assert!(cur.is_null());
cur.move_next();
assert!(cur.peek_prev().is_null());
assert!(!cur.is_null());
assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
{
let mut cur2 = cur.as_cursor();
assert_eq!(cur2.get().unwrap() as *const _, a.as_ref() as *const _);
assert_eq!(cur2.peek_next().get().unwrap().value, 2);
cur2.move_next();
assert_eq!(cur2.get().unwrap().value, 2);
cur2.move_next();
assert_eq!(cur2.peek_prev().get().unwrap().value, 2);
assert_eq!(cur2.get().unwrap() as *const _, c.as_ref() as *const _);
cur2.move_prev();
assert_eq!(cur2.get().unwrap() as *const _, b.as_ref() as *const _);
cur2.move_next();
assert_eq!(cur2.get().unwrap() as *const _, c.as_ref() as *const _);
cur2.move_next();
assert!(cur2.is_null());
assert!(cur2.clone().get().is_none());
}
assert_eq!(cur.get().unwrap() as *const _, a.as_ref() as *const _);
let a2 = make_obj(1);
let b2 = make_obj(2);
let c2 = make_obj(3);
assert_eq!(
cur.replace_with(a2.clone()).unwrap().as_ref() as *const _,
a.as_ref() as *const _
);
assert!(!a.link.is_linked());
cur.move_next();
assert_eq!(
cur.replace_with(b2.clone()).unwrap().as_ref() as *const _,
b.as_ref() as *const _
);
assert!(!b.link.is_linked());
cur.move_next();
assert_eq!(
cur.replace_with(c2.clone()).unwrap().as_ref() as *const _,
c.as_ref() as *const _
);
assert!(!c.link.is_linked());
cur.move_next();
assert_eq!(
cur.replace_with(c.clone()).unwrap_err().as_ref() as *const _,
c.as_ref() as *const _
);
}
#[cfg(not(miri))]
#[test]
fn test_insert_remove() {
let v = (0..100).map(make_obj).collect::<Vec<_>>();
assert!(v.iter().all(|x| !x.link.is_linked()));
let mut t = RBTree::new(ObjAdapter::new());
assert!(t.is_empty());
let mut rng = XorShiftRng::seed_from_u64(0);
{
let mut expected = Vec::new();
for x in v.iter() {
t.insert(x.clone());
expected.push(x.value);
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
while let Some(x) = t.front_mut().remove() {
assert_eq!(x.value, expected.remove(0));
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
assert!(expected.is_empty());
assert!(t.is_empty());
}
{
let mut expected = Vec::new();
for x in v.iter().rev() {
t.insert(x.clone());
expected.insert(0, x.value);
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
while let Some(x) = t.back_mut().remove() {
assert_eq!(x.value, expected.pop().unwrap());
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
assert!(expected.is_empty());
assert!(t.is_empty());
}
{
let mut indices = (0..v.len()).collect::<Vec<_>>();
indices.shuffle(&mut rng);
let mut expected = Vec::new();
for i in indices {
t.insert(v[i].clone());
expected.push(v[i].value);
expected[..].sort();
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
while !expected.is_empty() {
{
let index = rng.gen_range(0, expected.len());
let mut c = t.cursor_mut();
for _ in 0..(index + 1) {
c.move_next();
}
assert_eq!(c.remove().unwrap().value, expected.remove(index));
}
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
assert!(t.is_empty());
}
{
let mut indices = (0..v.len()).collect::<Vec<_>>();
indices.shuffle(&mut rng);
let mut expected = Vec::new();
for i in indices {
{
let mut c = t.front_mut();
loop {
if let Some(x) = c.get() {
if x.value > v[i].value {
break;
}
} else {
break;
}
c.move_next();
}
c.insert_before(v[i].clone());
}
expected.push(v[i].value);
expected[..].sort();
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
t.clear();
assert!(t.is_empty());
}
{
let mut indices = (0..v.len()).collect::<Vec<_>>();
indices.shuffle(&mut rng);
let mut expected = Vec::new();
for i in indices {
{
let mut c = t.back_mut();
loop {
if let Some(x) = c.get() {
if x.value < v[i].value {
break;
}
} else {
break;
}
c.move_prev();
}
c.insert_after(v[i].clone());
}
expected.push(v[i].value);
expected[..].sort();
assert_eq!(t.iter().map(|x| x.value).collect::<Vec<_>>(), expected);
}
}
}
#[cfg(not(miri))]
#[test]
fn test_iter() {
let v = (0..10).map(|x| make_obj(x * 10)).collect::<Vec<_>>();
let mut t = RBTree::new(ObjAdapter::new());
for x in v.iter() {
t.insert(x.clone());
}
assert_eq!(
format!("{:?}", t),
"{0, 10, 20, 30, 40, 50, 60, 70, 80, 90}"
);
assert_eq!(
t.iter().clone().map(|x| x.value).collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
(&t).into_iter().rev().map(|x| x.value).collect::<Vec<_>>(),
vec![90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
);
assert_eq!(
t.range(Unbounded, Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
t.range(Included(&0), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
t.range(Excluded(&0), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![10, 20, 30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
t.range(Included(&25), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
t.range(Excluded(&25), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
t.range(Included(&70), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![70, 80, 90]
);
assert_eq!(
t.range(Excluded(&70), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![80, 90]
);
assert_eq!(
t.range(Included(&100), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&100), Unbounded)
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Unbounded, Included(&90))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
);
assert_eq!(
t.range(Unbounded, Excluded(&90))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60, 70, 80]
);
assert_eq!(
t.range(Unbounded, Included(&25))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20]
);
assert_eq!(
t.range(Unbounded, Excluded(&25))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20]
);
assert_eq!(
t.range(Unbounded, Included(&70))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60, 70]
);
assert_eq!(
t.range(Unbounded, Excluded(&70))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![0, 10, 20, 30, 40, 50, 60]
);
assert_eq!(
t.range(Unbounded, Included(&-1))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Unbounded, Excluded(&-1))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Included(&25), Included(&80))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![30, 40, 50, 60, 70, 80]
);
assert_eq!(
t.range(Included(&25), Excluded(&80))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![30, 40, 50, 60, 70]
);
assert_eq!(
t.range(Excluded(&25), Included(&80))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![30, 40, 50, 60, 70, 80]
);
assert_eq!(
t.range(Excluded(&25), Excluded(&80))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![30, 40, 50, 60, 70]
);
assert_eq!(
t.range(Included(&25), Included(&25))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Included(&25), Excluded(&25))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&25), Included(&25))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&25), Excluded(&25))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Included(&50), Included(&50))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![50]
);
assert_eq!(
t.range(Included(&50), Excluded(&50))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&50), Included(&50))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&50), Excluded(&50))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Included(&100), Included(&-2))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Included(&100), Excluded(&-2))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&100), Included(&-2))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
assert_eq!(
t.range(Excluded(&100), Excluded(&-2))
.map(|x| x.value)
.collect::<Vec<_>>(),
vec![]
);
let mut v2 = Vec::new();
for x in t.take() {
v2.push(x.value);
}
assert_eq!(v2, vec![0, 10, 20, 30, 40, 50, 60, 70, 80, 90]);
assert!(t.is_empty());
for _ in t.take() {
unreachable!();
}
for x in v.iter() {
t.insert(x.clone());
}
v2.clear();
for x in t.into_iter().rev() {
v2.push(x.value);
}
assert_eq!(v2, vec![90, 80, 70, 60, 50, 40, 30, 20, 10, 0]);
}
#[test]
fn test_find() {
let v = (0..10).map(|x| make_obj(x * 10)).collect::<Vec<_>>();
let mut t = RBTree::new(ObjAdapter::new());
for x in v.iter() {
t.insert(x.clone());
}
for i in -9..100 {
fn mod10(x: i32) -> i32 {
if x < 0 {
10 + x % 10
} else {
x % 10
}
}
{
let c = t.find(&i);
assert_eq!(
c.get().map(|x| x.value),
if i % 10 == 0 { Some(i) } else { None }
);
}
{
let c = t.find_mut(&i);
assert_eq!(
c.get().map(|x| x.value),
if i % 10 == 0 { Some(i) } else { None }
);
}
{
let c = t.upper_bound(Unbounded);
assert_eq!(c.get().map(|x| x.value), Some(90));
}
{
let c = t.upper_bound_mut(Unbounded);
assert_eq!(c.get().map(|x| x.value), Some(90));
}
{
let c = t.upper_bound(Included(&i));
assert_eq!(
c.get().map(|x| x.value),
if i >= 0 { Some(i - mod10(i)) } else { None }
);
}
{
let c = t.upper_bound_mut(Included(&i));
assert_eq!(
c.get().map(|x| x.value),
if i >= 0 { Some(i - mod10(i)) } else { None }
);
}
{
let c = t.upper_bound(Excluded(&i));
assert_eq!(
c.get().map(|x| x.value),
if i > 0 {
Some(i - 1 - mod10(i - 1))
} else {
None
}
);
}
{
let c = t.upper_bound_mut(Excluded(&i));
assert_eq!(
c.get().map(|x| x.value),
if i > 0 {
Some(i - 1 - mod10(i - 1))
} else {
None
}
);
}
{
let c = t.lower_bound(Unbounded);
assert_eq!(c.get().map(|x| x.value), Some(0));
}
{
let c = t.lower_bound_mut(Unbounded);
assert_eq!(c.get().map(|x| x.value), Some(0));
}
{
let c = t.lower_bound(Included(&i));
assert_eq!(
c.get().map(|x| x.value),
if i <= 90 {
Some((i + 9) - mod10(i + 9))
} else {
None
}
);
}
{
let c = t.lower_bound_mut(Included(&i));
assert_eq!(
c.get().map(|x| x.value),
if i <= 90 {
Some((i + 9) - mod10(i + 9))
} else {
None
}
);
}
{
let c = t.lower_bound(Excluded(&i));
assert_eq!(
c.get().map(|x| x.value),
if i < 90 {
Some((i + 10) - mod10(i + 10))
} else {
None
}
);
}
{
let c = t.lower_bound_mut(Excluded(&i));
assert_eq!(
c.get().map(|x| x.value),
if i < 90 {
Some((i + 10) - mod10(i + 10))
} else {
None
}
);
}
}
}
#[test]
fn test_fast_clear() {
let mut t = RBTree::new(ObjAdapter::new());
let a = make_obj(1);
let b = make_obj(2);
let c = make_obj(3);
t.insert(a.clone());
t.insert(b.clone());
t.insert(c.clone());
t.fast_clear();
assert!(t.is_empty());
assert!(a.link.is_linked());
assert!(b.link.is_linked());
assert!(c.link.is_linked());
unsafe {
a.link.force_unlink();
b.link.force_unlink();
c.link.force_unlink();
}
assert!(t.is_empty());
assert!(!a.link.is_linked());
assert!(!b.link.is_linked());
assert!(!c.link.is_linked());
}
#[test]
fn test_entry() {
let mut t = RBTree::new(ObjAdapter::new());
let a = make_obj(1);
let b = make_obj(2);
let c = make_obj(3);
let d = make_obj(4);
let e = make_obj(5);
let f = make_obj(6);
t.entry(&3).or_insert(c.clone());
t.entry(&2).or_insert(b.clone());
t.entry(&1).or_insert(a.clone());
match t.entry(&2) {
Entry::Vacant(_) => unreachable!(),
Entry::Occupied(c) => assert_eq!(c.get().unwrap().value, 2),
}
assert_eq!(t.entry(&2).or_insert(b.clone()).get().unwrap().value, 2);
assert_eq!(
t.entry(&2)
.or_insert_with(|| b.clone())
.get()
.unwrap()
.value,
2
);
match t.entry(&5) {
Entry::Vacant(c) => assert_eq!(c.insert(e.clone()).get().unwrap().value, 5),
Entry::Occupied(_) => unreachable!(),
}
assert!(e.link.is_linked());
assert_eq!(t.entry(&4).or_insert(d.clone()).get().unwrap().value, 4);
assert!(d.link.is_linked());
assert_eq!(
t.entry(&6)
.or_insert_with(|| f.clone())
.get()
.unwrap()
.value,
6
);
assert!(f.link.is_linked());
}
#[test]
fn test_non_static() {
#[derive(Clone)]
struct Obj<'a, T> {
link: Link,
value: &'a T,
}
intrusive_adapter!(ObjAdapter<'a, T> = &'a Obj<'a, T>: Obj<'a, T> {link: Link} where T: 'a);
impl<'a, 'b, T: 'a + 'b> KeyAdapter<'a> for ObjAdapter<'b, T> {
type Key = &'a T;
fn get_key(&self, value: &'a Obj<'b, T>) -> &'a T {
value.value
}
}
let v = 5;
let a = Obj {
link: Link::default(),
value: &v,
};
let b = a.clone();
let mut l = RBTree::new(ObjAdapter::new());
l.insert(&a);
l.insert(&b);
assert_eq!(*l.front().get().unwrap().value, 5);
assert_eq!(*l.back().get().unwrap().value, 5);
}
macro_rules! test_clone_pointer {
($ptr: ident, $ptr_import: path) => {
use $ptr_import;
#[derive(Clone)]
struct Obj {
link: Link,
value: usize,
}
intrusive_adapter!(ObjAdapter = $ptr<Obj>: Obj { link: Link });
impl<'a> KeyAdapter<'a> for ObjAdapter {
type Key = usize;
fn get_key(&self, value: &'a Obj) -> usize {
value.value
}
}
let a = $ptr::new(Obj {
link: Link::new(),
value: 5,
});
let mut l = RBTree::new(ObjAdapter::new());
l.insert(a.clone());
assert_eq!(2, $ptr::strong_count(&a));
let pointer = l.front().clone_pointer().unwrap();
assert_eq!(pointer.value, 5);
assert_eq!(3, $ptr::strong_count(&a));
l.front_mut().remove();
assert!(l.front().clone_pointer().is_none());
};
}
#[test]
fn test_clone_pointer_rc() {
test_clone_pointer!(Rc, std::rc::Rc);
}
#[test]
fn test_clone_pointer_arc() {
test_clone_pointer!(Arc, std::sync::Arc);
}
}