1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
mod head;
mod iter;
mod node;
mod update;
pub use iter::AvltrieeIter;
pub use node::AvltrieeNode;
pub use update::AvltrieeHolder;
use std::{cmp::Ordering, num::NonZeroU32, ops::Deref, ptr::NonNull};
#[derive(Debug)]
pub struct Found {
row: u32,
ord: Ordering,
}
impl Found {
pub fn row(&self) -> u32 {
self.row
}
pub fn ord(&self) -> Ordering {
self.ord
}
}
pub struct Avltriee<T> {
node_list: NonNull<AvltrieeNode<T>>,
}
impl<T> Avltriee<T> {
/// Creates the Avltriee<T>.
/// #Examples
///
/// ```
/// use std::ptr::NonNull;
/// use avltriee::{Avltriee,AvltrieeNode};
/// let mut list: Vec<AvltrieeNode<i64>> = (0..=100)
/// .map(|_| AvltrieeNode::new(0, 0, 0))
/// .collect();
/// let mut t = Avltriee::new(unsafe { NonNull::new_unchecked(list.as_mut_ptr()) });
/// ```
pub fn new(node_list: NonNull<AvltrieeNode<T>>) -> Avltriee<T> {
Avltriee { node_list }
}
/// Returns the node of the specified row.
/// # Safety
/// Specifies a row within the allocated memory range.
pub unsafe fn node<'a>(&self, row: NonZeroU32) -> Option<&'a AvltrieeNode<T>> {
let node = self.offset(row.get());
(node.height > 0).then_some(node)
}
/// Returns the value of the specified row.
/// # Safety
/// Specifies a row within the allocated memory range.
pub unsafe fn value(&self, row: NonZeroU32) -> Option<&T> {
self.node(row).map(|x| x.deref())
}
/// Returns the value of the specified row. Does not check for the existence of row.
/// # Safety
/// Specifies a row within the allocated memory range.
pub unsafe fn value_unchecked(&self, row: NonZeroU32) -> &T {
self.offset(row.get())
}
/// Finds the end of a node from the specified value. Returns [Ordering::Equal] for exact match.
pub fn search_end<F>(&self, cmp: F) -> Found
where
F: Fn(&T) -> Ordering,
{
let mut row = self.root();
let mut ord = Ordering::Equal;
while row != 0 {
let node = unsafe { self.offset(row) };
ord = cmp(node);
match ord {
Ordering::Greater => {
if node.left == 0 {
break;
}
row = node.left;
}
Ordering::Equal => {
break;
}
Ordering::Less => {
if node.right == 0 {
break;
}
row = node.right;
}
}
}
Found { row, ord }
}
/// Checks whether the specified row is a node with a unique value.
/// # Safety
/// Specifies a row within the allocated memory range.
pub unsafe fn is_unique(&self, row: NonZeroU32) -> bool {
let node = self.offset(row.get());
node.same == 0 && (node.parent == 0 || self.offset(node.parent).same != row.get())
}
unsafe fn offset<'a>(&self, offset: u32) -> &'a AvltrieeNode<T> {
&*self.node_list.as_ptr().offset(offset as isize)
}
unsafe fn offset_mut<'a>(&mut self, offset: u32) -> &'a mut AvltrieeNode<T> {
&mut *self.node_list.as_ptr().offset(offset as isize)
}
fn min(&self, t: u32) -> u32 {
let mut t = t;
while t != 0 {
let l = unsafe { self.offset(t) }.left;
if l == 0 {
break;
}
t = l;
}
t
}
fn max(&self, t: u32) -> u32 {
let mut t = t;
while t != 0 {
let r = unsafe { self.offset(t) }.right;
if r == 0 {
break;
}
t = r;
}
t
}
}