Skip to main content

embed_avl/
lib.rs

1#![allow(rustdoc::redundant_explicit_links)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![cfg_attr(docsrs, allow(unused_attributes))]
4#![cfg_attr(not(feature = "std"), no_std)]
5
6//! An intrusive AVL tree implementation.
7//!
8//! The algorithm origin from open-zfs
9//!
10//! The ordering of avl tree is defined by [AvlItem] trait. There're two scenario:
11//! - borrow field as key from the node struct
12//! - impl Ord for struct itself
13//!
14//! Refer to the example of [AvlItem] document.
15//!
16//! # Examples
17//!
18//! ## Using `Box` to search and remove by key
19//!
20//! ```rust
21//! use embed_avl::{AvlTree, AvlItem, AvlNode};
22//! use core::cell::UnsafeCell;
23//! use core::cmp::Ordering;
24//! extern crate alloc;
25//! use alloc::sync::Arc;
26//!
27//! struct MyNode {
28//!     value: i32,
29//!     avl_node: UnsafeCell<AvlNode<MyNode, ()>>,
30//! }
31//!
32//! unsafe impl AvlItem<()> for MyNode {
33//!
34//!     type Key = i32;
35//!
36//!     fn get_node(&self) -> &mut AvlNode<MyNode, ()> {
37//!         unsafe { &mut *self.avl_node.get() }
38//!     }
39//!
40//!     fn borrow_key(&self) -> &Self::Key {
41//!         &self.value
42//!     }
43//! }
44//!
45//! // A boxed example
46//!
47//! let mut tree = AvlTree::<Box<MyNode>, ()>::new();
48//! tree.add(Box::new(MyNode { value: 10, avl_node: UnsafeCell::new(Default::default()) }));
49//!
50//! // Search and remove
51//! if let Some(node) = tree.remove_by_key(&10) {
52//!     assert_eq!(node.value, 10);
53//! }
54//! assert!(tree.is_empty());
55//!
56//! // Using `Arc` for multiple ownership
57//! // remove_ref only available to `Arc` and `Rc`
58//!
59//! let mut tree = AvlTree::<Arc<MyNode>, ()>::new();
60//! let node = Arc::new(MyNode { value: 42, avl_node: UnsafeCell::new(Default::default()) });
61//!
62//! tree.add(node.clone());
63//! assert_eq!(tree.len(), 1);
64//!
65//! // Remove by reference (detach from avl tree)
66//! tree.remove_ref(&node);
67//! assert_eq!(tree.len(), 0);
68//! ```
69
70extern crate alloc;
71#[cfg(any(feature = "std", test))]
72extern crate std;
73
74mod iter;
75pub use iter::*;
76#[cfg(test)]
77mod tests;
78
79use alloc::rc::Rc;
80use alloc::sync::Arc;
81use alloc::vec::Vec;
82use core::marker::PhantomData;
83use core::{
84    cmp::{Ordering, PartialEq},
85    fmt, mem,
86    ptr::{NonNull, null},
87};
88use pointers::Pointer;
89
90/// A trait to return internal mutable AvlNode for specified list.
91///
92/// The tag is used to distinguish different AvlNodes within the same item,
93/// allowing an item to belong to multiple lists simultaneously.
94/// For only one ownership, you can use `()`.
95///
96/// # Safety
97///
98/// Implementors must ensure `get_node` returns a valid reference to the `AvlNode`
99/// embedded within `Self`. Users must use `UnsafeCell` to hold `AvlNode` to support
100/// interior mutability required by list operations.
101///
102/// # Example (struct field as key)
103///
104/// ```
105/// use embed_avl::{AvlItem, AvlNode};
106/// use core::cell::UnsafeCell;
107///
108/// pub struct IntAvlNode {
109///     pub value: i64,
110///     pub node: UnsafeCell<AvlNode<Self, ()>>,
111/// }
112/// unsafe impl AvlItem<()> for IntAvlNode {
113///     type Key = i64;
114///
115///     fn get_node(&self) -> &mut AvlNode<Self, ()> {
116///         unsafe { &mut *self.node.get() }
117///     }
118///
119///     fn borrow_key(&self) -> &Self::Key {
120///         &self.value
121///     }
122/// }
123/// ```
124///
125/// # Example (impl Ord for struct)
126///
127/// ```
128/// use embed_avl::{AvlItem, AvlNode};
129/// use core::cell::{Cell, UnsafeCell};
130/// use core::cmp::Ordering;
131///
132/// pub struct RangeSeg {
133///     node: UnsafeCell<AvlNode<Self, ()>>,
134///     pub start: Cell<u64>,
135///     pub end: Cell<u64>,
136/// }
137///
138/// impl PartialOrd for RangeSeg {
139///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
140///         Some(Ord::cmp(self, other))
141///     }
142/// }
143/// impl PartialEq for RangeSeg {
144///     fn eq(&self, other: &Self) -> bool {
145///         Ord::cmp(self, other) == Ordering::Equal
146///     }
147/// }
148/// impl Eq for RangeSeg {}
149///
150/// impl Ord for RangeSeg {
151///     fn cmp(&self, other: &Self) -> Ordering {
152///         if self.end.get() <= other.start.get() {
153///             Ordering::Less
154///         } else if self.start.get() >= other.end.get() {
155///             Ordering::Greater
156///         } else {
157///             // intersection
158///             Ordering::Equal
159///         }
160///     }
161/// }
162/// unsafe impl Send for RangeSeg {}
163/// unsafe impl AvlItem<()> for RangeSeg {
164///     type Key = Self;
165///
166///     fn get_node(&self) -> &mut AvlNode<Self, ()> {
167///         unsafe { &mut *self.node.get() }
168///     }
169///
170///     fn borrow_key(&self) -> &Self::Key {
171///         self
172///     }
173/// }
174/// ```
175pub unsafe trait AvlItem<Tag>: Sized {
176    type Key: Ord;
177
178    fn get_node(&self) -> &mut AvlNode<Self, Tag>;
179
180    #[inline(always)]
181    fn cmp(&self, other: &Self) -> Ordering {
182        self.borrow_key().cmp(other.borrow_key())
183    }
184
185    #[inline(always)]
186    fn cmp_key(&self, key: &Self::Key) -> Ordering {
187        key.cmp(self.borrow_key())
188    }
189
190    fn borrow_key(&self) -> &Self::Key;
191}
192
193#[derive(PartialEq, Debug, Copy, Clone)]
194pub enum AvlDirection {
195    Left = 0,
196    Right = 1,
197}
198
199impl AvlDirection {
200    #[inline(always)]
201    fn reverse(self) -> AvlDirection {
202        match self {
203            AvlDirection::Left => AvlDirection::Right,
204            AvlDirection::Right => AvlDirection::Left,
205        }
206    }
207}
208
209macro_rules! avlchild_to_balance {
210    ( $dir: expr ) => {
211        match $dir {
212            AvlDirection::Left => -1,
213            AvlDirection::Right => 1,
214        }
215    };
216}
217
218macro_rules! as_avlitem {
219    ($P: tt, $Tag: tt, $name: ident) => {
220        <$P::Target as AvlItem<$Tag>>::$name
221    };
222}
223
224pub struct AvlNode<T: AvlItem<Tag>, Tag> {
225    pub left: *const T,
226    pub right: *const T,
227    pub parent: *const T,
228    pub balance: i8,
229    _phan: PhantomData<fn(&Tag)>,
230}
231
232unsafe impl<T: AvlItem<Tag> + Send, Tag> Send for AvlNode<T, Tag> {}
233
234impl<T: AvlItem<Tag>, Tag> AvlNode<T, Tag> {
235    #[inline(always)]
236    pub fn detach(&mut self) {
237        self.left = null();
238        self.right = null();
239        self.parent = null();
240        self.balance = 0;
241    }
242
243    #[inline(always)]
244    fn get_child(&self, dir: AvlDirection) -> *const T {
245        match dir {
246            AvlDirection::Left => self.left,
247            AvlDirection::Right => self.right,
248        }
249    }
250
251    #[inline(always)]
252    fn set_child(&mut self, dir: AvlDirection, child: *const T) {
253        match dir {
254            AvlDirection::Left => self.left = child,
255            AvlDirection::Right => self.right = child,
256        }
257    }
258
259    #[inline(always)]
260    fn get_parent(&self) -> *const T {
261        self.parent
262    }
263
264    // Swap two node but not there value
265    #[inline(always)]
266    pub fn swap(&mut self, other: &mut AvlNode<T, Tag>) {
267        mem::swap(&mut self.left, &mut other.left);
268        mem::swap(&mut self.right, &mut other.right);
269        mem::swap(&mut self.parent, &mut other.parent);
270        mem::swap(&mut self.balance, &mut other.balance);
271    }
272}
273
274impl<T: AvlItem<Tag>, Tag> Default for AvlNode<T, Tag> {
275    fn default() -> Self {
276        Self { left: null(), right: null(), parent: null(), balance: 0, _phan: Default::default() }
277    }
278}
279
280#[allow(unused_must_use)]
281impl<T: AvlItem<Tag>, Tag> fmt::Debug for AvlNode<T, Tag> {
282    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
283        write!(f, "(")?;
284
285        if !self.left.is_null() {
286            write!(f, "left: {:p}", self.left)?;
287        } else {
288            write!(f, "left: none ")?;
289        }
290
291        if !self.right.is_null() {
292            write!(f, "right: {:p}", self.right)?;
293        } else {
294            write!(f, "right: none ")?;
295        }
296        write!(f, ")")
297    }
298}
299
300pub type AvlCmpFunc<K, T> = fn(&K, &T) -> Ordering;
301
302/// An intrusive AVL tree (balanced binary search tree).
303///
304/// Elements in the tree must implement the [`AvlItem`] trait.
305/// The tree supports various pointer types (`Box`, `Arc`, `Rc`, etc.) through the [`Pointer`] trait.
306pub struct AvlTree<P, Tag>
307where
308    P: Pointer,
309    P::Target: AvlItem<Tag>,
310{
311    root: *const P::Target,
312    count: usize,
313    _phan: PhantomData<fn(P, &Tag)>,
314}
315
316unsafe impl<P, Tag> Send for AvlTree<P, Tag>
317where
318    P: Pointer + Send,
319    P::Target: AvlItem<Tag>,
320{
321}
322
323/// Result of a search operation in an [`AvlTree`].
324///
325/// An `AvlSearchResult` identifies either:
326/// 1. An exact match: `direction` is `None` and `node` points to the matching item.
327/// 2. An insertion point: `direction` is `Some(dir)` and `node` points to the parent
328///    where a new node should be attached as the `dir` child.
329///
330/// The lifetime `'a` ties the search result to the tree's borrow, ensuring safety.
331/// However, this lifetime often prevents further mutable operations on the tree
332/// (e.g., adding a node while holding the search result). Use [`detach`](Self::detach)
333/// to de-couple the result from the tree's lifetime when necessary.
334pub struct AvlSearchResult<'a, P: Pointer> {
335    /// The matching node or the parent for insertion.
336    pub node: *const P::Target,
337    /// `None` if exact match found, or `Some(direction)` indicating insertion point.
338    pub direction: Option<AvlDirection>,
339    _phan: PhantomData<&'a P::Target>,
340}
341
342impl<P: Pointer> Default for AvlSearchResult<'_, P> {
343    fn default() -> Self {
344        AvlSearchResult { node: null(), direction: Some(AvlDirection::Left), _phan: PhantomData }
345    }
346}
347
348impl<'a, P: Pointer> AvlSearchResult<'a, P> {
349    /// Returns a reference to the matching node if the search was an exact match.
350    #[inline(always)]
351    pub fn get_node_ref(&self) -> Option<&'a P::Target> {
352        if self.is_exact() { unsafe { self.node.as_ref() } } else { None }
353    }
354
355    /// Returns `true` if the search result is an exact match.
356    #[inline(always)]
357    pub fn is_exact(&self) -> bool {
358        self.direction.is_none() && !self.node.is_null()
359    }
360
361    /// De-couple the lifetime of the search result from the tree.
362    ///
363    /// This method is essential for performing mutable operations on the tree
364    /// using search results. In Rust, a search result typically borrows the tree
365    /// immutably. If you need to modify the tree (e.g., call `insert` or `remove`)
366    /// based on that result, the borrow checker would normally prevent it.
367    ///
368    /// `detach` effectively "erases" the lifetime `'a`, returning a result with
369    /// an unbounded lifetime `'b`.
370    ///
371    /// # Examples
372    ///
373    /// Used in `RangeTree::add`:
374    /// ```ignore
375    /// let result = self.root.find(&rs_key);
376    /// // result is AvlSearchResult<'a, ...> and borrows self.root
377    ///
378    /// let detached = unsafe { result.detach() };
379    /// // detached has no lifetime bound to self.root
380    ///
381    /// self.space += size; // Mutable operation on self permitted
382    /// self.merge_seg(start, end, detached); // Mutation on tree permitted
383    /// ```
384    ///
385    /// # Safety
386    /// This is an unsafe operation. The compiler no longer protects the validity
387    /// of the internal pointer via lifetimes. You must ensure that the tree
388    /// structure is not modified in a way that invalidates `node` (e.g., the
389    /// parent node being removed) before using the detached result.
390    #[inline(always)]
391    pub unsafe fn detach<'b>(&'a self) -> AvlSearchResult<'b, P> {
392        AvlSearchResult { node: self.node, direction: self.direction, _phan: PhantomData }
393    }
394
395    /// Return the nearest node in the search result
396    #[inline(always)]
397    pub fn get_nearest(&self) -> Option<&P::Target> {
398        if self.node.is_null() { None } else { unsafe { self.node.as_ref() } }
399    }
400}
401
402impl<'a, T> AvlSearchResult<'a, Arc<T>> {
403    /// Returns the matching Arc node if this is an exact match.
404    pub fn get_exact(&self) -> Option<Arc<T>> {
405        if self.is_exact() {
406            unsafe {
407                Arc::increment_strong_count(self.node);
408                Some(Arc::from_raw(self.node))
409            }
410        } else {
411            None
412        }
413    }
414}
415
416impl<'a, T> AvlSearchResult<'a, Rc<T>> {
417    /// Returns the matching Rc node if this is an exact match.
418    pub fn get_exact(&self) -> Option<Rc<T>> {
419        if self.is_exact() {
420            unsafe {
421                Rc::increment_strong_count(self.node);
422                Some(Rc::from_raw(self.node))
423            }
424        } else {
425            None
426        }
427    }
428}
429
430macro_rules! return_end {
431    ($tree: expr, $dir: expr) => {{ if $tree.root.is_null() { null() } else { $tree.bottom_child_ref($tree.root, $dir) } }};
432}
433
434macro_rules! balance_to_child {
435    ($balance: expr) => {
436        match $balance {
437            0 | 1 => AvlDirection::Left,
438            _ => AvlDirection::Right,
439        }
440    };
441}
442
443impl<P, Tag> AvlTree<P, Tag>
444where
445    P: Pointer,
446    P::Target: AvlItem<Tag>,
447{
448    /// Creates a new, empty `AvlTree`.
449    #[inline]
450    pub fn new() -> Self {
451        AvlTree { count: 0, root: null(), _phan: Default::default() }
452    }
453
454    /// Returns an iterator that removes all elements from the tree in post-order.
455    ///
456    /// This is an optimized, non-recursive, and stack-less traversal that preserves
457    /// tree invariants during destruction.
458    #[inline]
459    pub fn drain(&mut self) -> AvlDrain<'_, P, Tag> {
460        AvlDrain::new(self)
461    }
462
463    #[inline]
464    pub fn is_empty(&self) -> bool {
465        self.count == 0
466    }
467
468    #[inline]
469    pub fn len(&self) -> usize {
470        self.count
471    }
472
473    /// Adds a new element to the tree, takes the ownership of P.
474    ///
475    /// The `cmp_func` should compare two elements to determine their relative order.
476    /// Returns `true` if the element was added, `false` if an equivalent element
477    /// already exists (in which case the provided `node` is dropped).
478    #[inline]
479    pub fn add(&mut self, node: P) -> bool {
480        if self.count == 0 && self.root.is_null() {
481            self.root = node.into_raw();
482            self.count = 1;
483            return true;
484        }
485
486        let w = self._find(node.as_ref(), as_avlitem!(P, Tag, cmp));
487        if w.direction.is_none() {
488            // To prevent memory leak, we must drop the node.
489            // But since we took ownership, we have to convert it back to P and drop it.
490            drop(node);
491            return false;
492        }
493
494        // Safety: We need to decouple the lifetime of 'w' from 'self' to call 'insert'.
495        // We extract the pointers and reconstruct the result.
496        let w_node = w.node;
497        let w_dir = w.direction;
498
499        let w_detached = AvlSearchResult { node: w_node, direction: w_dir, _phan: PhantomData };
500
501        self.insert(node, w_detached);
502        true
503    }
504
505    /// Inserts a new node into the tree at the location specified by a search result.
506    ///
507    /// This is typically used after a [`find`](Self::find) operation didn't find an exact match.
508    ///
509    /// # Safety
510    ///
511    /// Once the tree structure changed, previous search result is not safe to use anymore.
512    ///
513    /// You should [detach()](AvlSearchResult::detach) the result before calling insert,
514    /// to avoid the borrowing issue.
515    ///
516    /// # Panics
517    /// Panics if the search result is an exact match (i.e. node already exists).
518    ///
519    /// # Examples
520    ///
521    /// ```rust
522    /// use embed_avl::{AvlTree, AvlItem, AvlNode};
523    /// use core::cell::UnsafeCell;
524    /// extern crate alloc;
525    /// use alloc::sync::Arc;
526    ///
527    /// struct MyNode {
528    ///     value: i32,
529    ///     avl_node: UnsafeCell<AvlNode<MyNode, ()>>,
530    /// }
531    ///
532    /// unsafe impl AvlItem<()> for MyNode {
533    ///     type Key = i32;
534    ///
535    ///     fn get_node(&self) -> &mut AvlNode<MyNode, ()> {
536    ///         unsafe { &mut *self.avl_node.get() }
537    ///     }
538    ///
539    ///     fn borrow_key(&self) -> &Self::Key {
540    ///         &self.value
541    ///     }
542    /// }
543    ///
544    /// let mut tree = AvlTree::<Arc<MyNode>, ()>::new();
545    /// let key = 42;
546    /// let result = tree.find(&key);
547    ///
548    /// if !result.is_exact() {
549    ///     let new_node = Arc::new(MyNode {
550    ///         value: key,
551    ///         avl_node: UnsafeCell::new(Default::default()),
552    ///     });
553    ///     tree.insert(new_node, unsafe{result.detach()});
554    /// }
555    /// ```
556    #[inline]
557    pub fn insert(&mut self, new_data: P, w: AvlSearchResult<'_, P>) {
558        debug_assert!(w.direction.is_some());
559        self._insert(new_data, w.node, w.direction.unwrap());
560    }
561
562    #[allow(clippy::not_unsafe_ptr_arg_deref)]
563    pub fn _insert(
564        &mut self,
565        new_data: P,
566        here: *const P::Target, // parent
567        mut which_child: AvlDirection,
568    ) {
569        let mut new_balance: i8;
570        let new_ptr = new_data.into_raw();
571
572        if here.is_null() {
573            if self.count > 0 {
574                panic!("insert into a tree size {} with empty where.node", self.count);
575            }
576            self.root = new_ptr;
577            self.count += 1;
578            return;
579        }
580
581        let parent = unsafe { &*here };
582        let node = unsafe { (*new_ptr).get_node() };
583        let parent_node = parent.get_node();
584        node.parent = here;
585        parent_node.set_child(which_child, new_ptr);
586        self.count += 1;
587
588        /*
589         * Now, back up the tree modifying the balance of all nodes above the
590         * insertion point. If we get to a highly unbalanced ancestor, we
591         * need to do a rotation.  If we back out of the tree we are done.
592         * If we brought any subtree into perfect balance (0), we are also done.
593         */
594        let mut data: *const P::Target = here;
595        loop {
596            let node = unsafe { (*data).get_node() };
597            let old_balance = node.balance;
598            new_balance = old_balance + avlchild_to_balance!(which_child);
599            if new_balance == 0 {
600                node.balance = 0;
601                return;
602            }
603            if old_balance != 0 {
604                self.rotate(data, new_balance);
605                return;
606            }
607            node.balance = new_balance;
608            let parent_ptr = node.get_parent();
609            if parent_ptr.is_null() {
610                return;
611            }
612            which_child = self.parent_direction(data, parent_ptr);
613            data = parent_ptr;
614        }
615    }
616
617    /// Insert "new_data" in "tree" in the given "direction" either after or
618    /// before AvlDirection::After, AvlDirection::Before) the data "here".
619    ///
620    /// Insertions can only be done at empty leaf points in the tree, therefore
621    /// if the given child of the node is already present we move to either
622    /// the AVL_PREV or AVL_NEXT and reverse the insertion direction. Since
623    /// every other node in the tree is a leaf, this always works.
624    ///
625    /// # Safety
626    ///
627    /// Once the tree structure changed, previous search result is not safe to use anymore.
628    ///
629    /// You should [detach()](AvlSearchResult::detach) the result before calling insert,
630    /// to avoid the borrowing issue.
631    pub unsafe fn insert_here(
632        &mut self, new_data: P, here: AvlSearchResult<P>, direction: AvlDirection,
633    ) {
634        let mut dir_child = direction;
635        assert!(!here.node.is_null());
636        let here_node = here.node;
637        let child = unsafe { (*here_node).get_node().get_child(dir_child) };
638        if !child.is_null() {
639            dir_child = dir_child.reverse();
640            let node = self.bottom_child_ref(child, dir_child);
641            self._insert(new_data, node, dir_child);
642        } else {
643            self._insert(new_data, here_node, dir_child);
644        }
645    }
646
647    // set child and both child's parent
648    #[inline(always)]
649    fn set_child2(
650        &mut self, node: &mut AvlNode<P::Target, Tag>, dir: AvlDirection, child: *const P::Target,
651        parent: *const P::Target,
652    ) {
653        if !child.is_null() {
654            unsafe { (*child).get_node().parent = parent };
655        }
656        node.set_child(dir, child);
657    }
658
659    #[inline(always)]
660    fn parent_direction(&self, data: *const P::Target, parent: *const P::Target) -> AvlDirection {
661        if !parent.is_null() {
662            let parent_node = unsafe { (*parent).get_node() };
663            if parent_node.left == data {
664                return AvlDirection::Left;
665            }
666            if parent_node.right == data {
667                return AvlDirection::Right;
668            }
669            panic!("invalid avl tree, node {:p}, parent {:p}", data, parent);
670        }
671        // this just follow zfs
672        AvlDirection::Left
673    }
674
675    #[inline(always)]
676    fn parent_direction2(&self, data: *const P::Target) -> AvlDirection {
677        let node = unsafe { (*data).get_node() };
678        let parent = node.get_parent();
679        if !parent.is_null() {
680            return self.parent_direction(data, parent);
681        }
682        // this just follow zfs
683        AvlDirection::Left
684    }
685
686    #[inline]
687    fn rotate(&mut self, data: *const P::Target, balance: i8) -> bool {
688        let dir = if balance < 0 { AvlDirection::Left } else { AvlDirection::Right };
689        let node = unsafe { (*data).get_node() };
690
691        let parent = node.get_parent();
692        let dir_inverse = dir.reverse();
693        let left_heavy = balance >> 1;
694        let right_heavy = -left_heavy;
695
696        let child = node.get_child(dir);
697        let child_node = unsafe { (*child).get_node() };
698        let mut child_balance = child_node.balance;
699
700        let which_child = self.parent_direction(data, parent);
701
702        // node is overly left heavy, the left child is balanced or also left heavy.
703        if child_balance != right_heavy {
704            child_balance += right_heavy;
705
706            let c_right = child_node.get_child(dir_inverse);
707            self.set_child2(node, dir, c_right, data);
708            // move node to be child's right child
709            node.balance = -child_balance;
710
711            node.parent = child;
712            child_node.set_child(dir_inverse, data);
713            // update the pointer into this subtree
714
715            child_node.balance = child_balance;
716            if !parent.is_null() {
717                child_node.parent = parent;
718                unsafe { (*parent).get_node() }.set_child(which_child, child);
719            } else {
720                child_node.parent = null();
721                self.root = child;
722            }
723            return child_balance == 0;
724        }
725        // When node is left heavy, but child is right heavy we use
726        // a different rotation.
727
728        let g_child = child_node.get_child(dir_inverse);
729        let g_child_node = unsafe { (*g_child).get_node() };
730        let g_left = g_child_node.get_child(dir);
731        let g_right = g_child_node.get_child(dir_inverse);
732
733        self.set_child2(node, dir, g_right, data);
734        self.set_child2(child_node, dir_inverse, g_left, child);
735
736        /*
737         * move child to left child of gchild and
738         * move node to right child of gchild and
739         * fixup parent of all this to point to gchild
740         */
741
742        let g_child_balance = g_child_node.balance;
743        if g_child_balance == right_heavy {
744            child_node.balance = left_heavy;
745        } else {
746            child_node.balance = 0;
747        }
748        child_node.parent = g_child;
749        g_child_node.set_child(dir, child);
750
751        if g_child_balance == left_heavy {
752            node.balance = right_heavy;
753        } else {
754            node.balance = 0;
755        }
756        g_child_node.balance = 0;
757
758        node.parent = g_child;
759        g_child_node.set_child(dir_inverse, data);
760
761        if !parent.is_null() {
762            g_child_node.parent = parent;
763            unsafe { (*parent).get_node() }.set_child(which_child, g_child);
764        } else {
765            g_child_node.parent = null();
766            self.root = g_child;
767        }
768        true
769    }
770
771    /*
772    fn replace(&mut self, old: *const P::Target, node: P) {
773        let old_node = unsafe { (*old).get_node() };
774        let new_ptr = node.into_raw();
775        let new_node = unsafe { (*new_ptr).get_node() };
776
777        let left = old_node.get_child(AvlDirection::Left);
778        if !left.is_null() {
779            self.set_child2(new_node, AvlDirection::Left, left, new_ptr);
780        }
781        let right = old_node.get_child(AvlDirection::Right);
782        if !right.is_null() {
783            self.set_child2(new_node, AvlDirection::Right, right, new_ptr);
784        }
785
786        new_node.balance = old_node.balance;
787        old_node.balance = 0;
788        let parent = old_node.get_parent();
789        if !parent.is_null() {
790            let dir = self.parent_direction(old, parent);
791            self.set_child2(unsafe { (*parent).get_node() }, dir, new_ptr, parent);
792            old_node.parent = null();
793        } else {
794            debug_assert_eq!(self.root, old);
795            self.root = new_ptr;
796        }
797    }
798    */
799
800    /// Requires `del` to be a valid pointer to a node in this tree.
801    ///
802    /// # Safety
803    ///
804    /// It does not drop the node data, only unlinks it.
805    /// Caller is responsible for re-taking ownership (e.g. via from_raw) and dropping if needed.
806    ///
807    /// For Arc/Rc, use [Self::remove_ref()] instead.
808    ///
809    pub unsafe fn remove(&mut self, del: *const P::Target) {
810        /*
811         * Deletion is easiest with a node that has at most 1 child.
812         * We swap a node with 2 children with a sequentially valued
813         * neighbor node. That node will have at most 1 child. Note this
814         * has no effect on the ordering of the remaining nodes.
815         *
816         * As an optimization, we choose the greater neighbor if the tree
817         * is right heavy, otherwise the left neighbor. This reduces the
818         * number of rotations needed.
819         */
820        if self.count == 0 {
821            return;
822        }
823        if self.count == 1 && self.root == del {
824            self.root = null();
825            self.count = 0;
826            unsafe { (*del).get_node().detach() };
827            return;
828        }
829        let mut which_child: AvlDirection;
830
831        // Use reference directly to get node, avoiding unsafe dereference of raw pointer
832        let del_node = unsafe { (*del).get_node() };
833
834        let node_swap_flag = !del_node.left.is_null() && !del_node.right.is_null();
835
836        if node_swap_flag {
837            let dir: AvlDirection = balance_to_child!(del_node.balance + 1);
838            let child_temp = del_node.get_child(dir);
839
840            let dir_inverse: AvlDirection = dir.reverse();
841            let child = self.bottom_child_ref(child_temp, dir_inverse);
842
843            // Fix Miri UB: Avoid calling parent_direction2(child) if child's parent is del,
844            // because that would create a aliasing &mut ref to del while we hold del_node.
845            let dir_child_temp =
846                if child == child_temp { dir } else { self.parent_direction2(child) };
847
848            // Fix Miri UB: Do not call parent_direction2(del) as it creates a new &mut AvlNode
849            // alias while we hold del_node. Use del_node to find parent direction.
850            let parent = del_node.get_parent();
851            let dir_child_del = if !parent.is_null() {
852                self.parent_direction(del, parent)
853            } else {
854                AvlDirection::Left
855            };
856
857            let child_node = unsafe { (*child).get_node() };
858            child_node.swap(del_node);
859
860            // move 'node' to delete's spot in the tree
861            if child_node.get_child(dir) == child {
862                // if node(d) left child is node(c)
863                child_node.set_child(dir, del);
864            }
865
866            let c_dir = child_node.get_child(dir);
867            if c_dir == del {
868                del_node.parent = child;
869            } else if !c_dir.is_null() {
870                unsafe { (*c_dir).get_node() }.parent = child;
871            }
872
873            let c_inv = child_node.get_child(dir_inverse);
874            if c_inv == del {
875                del_node.parent = child;
876            } else if !c_inv.is_null() {
877                unsafe { (*c_inv).get_node() }.parent = child;
878            }
879
880            let parent = child_node.get_parent();
881            if !parent.is_null() {
882                unsafe { (*parent).get_node() }.set_child(dir_child_del, child);
883            } else {
884                self.root = child;
885            }
886
887            // Put tmp where node used to be (just temporary).
888            // It always has a parent and at most 1 child.
889            let parent = del_node.get_parent();
890            unsafe { (*parent).get_node() }.set_child(dir_child_temp, del);
891            if !del_node.right.is_null() {
892                which_child = AvlDirection::Right;
893            } else {
894                which_child = AvlDirection::Left;
895            }
896            let child = del_node.get_child(which_child);
897            if !child.is_null() {
898                unsafe { (*child).get_node() }.parent = del;
899            }
900            which_child = dir_child_temp;
901        } else {
902            // Fix Miri UB here as well
903            let parent = del_node.get_parent();
904            if !parent.is_null() {
905                which_child = self.parent_direction(del, parent);
906            } else {
907                which_child = AvlDirection::Left;
908            }
909        }
910
911        // Here we know "delete" is at least partially a leaf node. It can
912        // be easily removed from the tree.
913        let parent: *const P::Target = del_node.get_parent();
914
915        let imm_data: *const P::Target =
916            if !del_node.left.is_null() { del_node.left } else { del_node.right };
917
918        // Connect parent directly to node (leaving out delete).
919        if !imm_data.is_null() {
920            let imm_node = unsafe { (*imm_data).get_node() };
921            imm_node.parent = parent;
922        }
923
924        if !parent.is_null() {
925            assert!(self.count > 0);
926            self.count -= 1;
927
928            let parent_node = unsafe { (*parent).get_node() };
929            parent_node.set_child(which_child, imm_data);
930
931            //Since the subtree is now shorter, begin adjusting parent balances
932            //and performing any needed rotations.
933            let mut node_data: *const P::Target = parent;
934            let mut old_balance: i8;
935            let mut new_balance: i8;
936            loop {
937                // Move up the tree and adjust the balance.
938                // Capture the parent and which_child values for the next
939                // iteration before any rotations occur.
940                let node = unsafe { (*node_data).get_node() };
941                old_balance = node.balance;
942                new_balance = old_balance - avlchild_to_balance!(which_child);
943
944                //If a node was in perfect balance but isn't anymore then
945                //we can stop, since the height didn't change above this point
946                //due to a deletion.
947                if old_balance == 0 {
948                    node.balance = new_balance;
949                    break;
950                }
951
952                let parent = node.get_parent();
953                which_child = self.parent_direction(node_data, parent);
954
955                //If the new balance is zero, we don't need to rotate
956                //else
957                //need a rotation to fix the balance.
958                //If the rotation doesn't change the height
959                //of the sub-tree we have finished adjusting.
960                if new_balance == 0 {
961                    node.balance = new_balance;
962                } else if !self.rotate(node_data, new_balance) {
963                    break;
964                }
965
966                if !parent.is_null() {
967                    node_data = parent;
968                    continue;
969                }
970                break;
971            }
972        } else if !imm_data.is_null() {
973            debug_assert!(self.count > 0);
974            self.count -= 1;
975            self.root = imm_data;
976        }
977        if self.root.is_null() && self.count > 0 {
978            panic!("AvlTree {} nodes left after remove but tree.root == nil", self.count);
979        }
980        del_node.detach();
981    }
982
983    /// Removes a node from the tree by key.
984    ///
985    /// The `cmp_func` should compare the key `K` with the elements in the tree.
986    /// Returns `Some(P)` if an exact match was found and removed, `None` otherwise.
987    #[inline]
988    pub fn remove_by_key(&mut self, val: &'_ as_avlitem!(P, Tag, Key)) -> Option<P> {
989        let result = self.find(val);
990        self.remove_with(unsafe { result.detach() })
991    }
992
993    /// remove with a previous search result
994    ///
995    /// - If the result is exact match, return the removed element ownership
996    /// - If the result is not exact match, return None
997    ///
998    /// # Safety
999    ///
1000    /// Once the tree structure changed, previous search result is not safe to use anymore.
1001    ///
1002    /// You should [detach()](AvlSearchResult::detach) the result before calling insert,
1003    /// to avoid the borrowing issue.
1004    #[inline]
1005    pub fn remove_with(&mut self, result: AvlSearchResult<'_, P>) -> Option<P> {
1006        if result.is_exact() {
1007            unsafe {
1008                let p = result.node;
1009                self.remove(p);
1010                Some(P::from_raw(p))
1011            }
1012        } else {
1013            None
1014        }
1015    }
1016
1017    /// Searches for an element in the tree.
1018    ///
1019    /// Returns an [`AvlSearchResult`] which indicates if an exact match was found,
1020    /// or where a new element should be inserted.
1021    #[inline]
1022    pub fn find<'a>(&'a self, val: &'_ as_avlitem!(P, Tag, Key)) -> AvlSearchResult<'a, P> {
1023        self._find::<as_avlitem!(P, Tag, Key)>(val, |_val, other| _val.cmp(other.borrow_key()))
1024    }
1025
1026    #[inline]
1027    fn _find<'a, K>(
1028        &'a self, val: &'_ K, cmp_func: AvlCmpFunc<K, P::Target>,
1029    ) -> AvlSearchResult<'a, P> {
1030        if self.root.is_null() {
1031            return AvlSearchResult::default();
1032        }
1033        let mut node_data = self.root;
1034        loop {
1035            let diff = cmp_func(val, unsafe { &*node_data });
1036            match diff {
1037                Ordering::Equal => {
1038                    return AvlSearchResult {
1039                        node: node_data,
1040                        direction: None,
1041                        _phan: PhantomData,
1042                    };
1043                }
1044                Ordering::Less => {
1045                    let node = unsafe { (*node_data).get_node() };
1046                    let left = node.get_child(AvlDirection::Left);
1047                    if left.is_null() {
1048                        return AvlSearchResult {
1049                            node: node_data,
1050                            direction: Some(AvlDirection::Left),
1051                            _phan: PhantomData,
1052                        };
1053                    }
1054                    node_data = left;
1055                }
1056                Ordering::Greater => {
1057                    let node = unsafe { (*node_data).get_node() };
1058                    let right = node.get_child(AvlDirection::Right);
1059                    if right.is_null() {
1060                        return AvlSearchResult {
1061                            node: node_data,
1062                            direction: Some(AvlDirection::Right),
1063                            _phan: PhantomData,
1064                        };
1065                    }
1066                    node_data = right;
1067                }
1068            }
1069        }
1070    }
1071
1072    // for range tree, val may overlap multiple range(node), ensure return the smallest
1073    #[inline]
1074    pub fn find_contained<'a>(
1075        &'a self, val: &'_ <P::Target as AvlItem<Tag>>::Key,
1076    ) -> Option<&'a P::Target> {
1077        if self.root.is_null() {
1078            return None;
1079        }
1080        let mut node_data = self.root;
1081        let mut result_node: *const P::Target = null();
1082        loop {
1083            let diff = unsafe { &*node_data }.cmp_key(val);
1084            match diff {
1085                Ordering::Equal => {
1086                    let node = unsafe { (*node_data).get_node() };
1087                    let left = node.get_child(AvlDirection::Left);
1088                    result_node = node_data;
1089                    if left.is_null() {
1090                        break;
1091                    } else {
1092                        node_data = left;
1093                    }
1094                }
1095                Ordering::Less => {
1096                    let node = unsafe { (*node_data).get_node() };
1097                    let left = node.get_child(AvlDirection::Left);
1098                    if left.is_null() {
1099                        break;
1100                    }
1101                    node_data = left;
1102                }
1103                Ordering::Greater => {
1104                    let node = unsafe { (*node_data).get_node() };
1105                    let right = node.get_child(AvlDirection::Right);
1106                    if right.is_null() {
1107                        break;
1108                    }
1109                    node_data = right;
1110                }
1111            }
1112        }
1113        if result_node.is_null() { None } else { unsafe { result_node.as_ref() } }
1114    }
1115
1116    // for slab, return any block larger or equal than search param
1117    #[inline]
1118    pub fn find_larger_eq<'a>(
1119        &'a self, val: &'_ <P::Target as AvlItem<Tag>>::Key,
1120    ) -> AvlSearchResult<'a, P> {
1121        if self.root.is_null() {
1122            return AvlSearchResult::default();
1123        }
1124        let mut node_data = self.root;
1125        loop {
1126            let diff = unsafe { &*node_data }.cmp_key(val);
1127            match diff {
1128                Ordering::Equal => {
1129                    return AvlSearchResult {
1130                        node: node_data,
1131                        direction: None,
1132                        _phan: PhantomData,
1133                    };
1134                }
1135                Ordering::Less => {
1136                    return AvlSearchResult {
1137                        node: node_data,
1138                        direction: None,
1139                        _phan: PhantomData,
1140                    };
1141                }
1142                Ordering::Greater => {
1143                    let right = unsafe { (*node_data).get_node() }.get_child(AvlDirection::Right);
1144                    if right.is_null() {
1145                        return AvlSearchResult {
1146                            node: null(),
1147                            direction: None,
1148                            _phan: PhantomData,
1149                        };
1150                    }
1151                    node_data = right;
1152                }
1153            }
1154        }
1155    }
1156
1157    /// For range tree
1158    #[inline]
1159    pub fn find_nearest<'a, K>(
1160        &'a self, val: &'_ <P::Target as AvlItem<Tag>>::Key,
1161    ) -> AvlSearchResult<'a, P> {
1162        if self.root.is_null() {
1163            return AvlSearchResult::default();
1164        }
1165
1166        let mut node_data = self.root;
1167        let mut nearest_node = null();
1168        loop {
1169            let diff = unsafe { &*node_data }.cmp_key(val);
1170            match diff {
1171                Ordering::Equal => {
1172                    return AvlSearchResult {
1173                        node: node_data,
1174                        direction: None,
1175                        _phan: PhantomData,
1176                    };
1177                }
1178                Ordering::Less => {
1179                    nearest_node = node_data;
1180                    let left = unsafe { (*node_data).get_node() }.get_child(AvlDirection::Left);
1181                    if left.is_null() {
1182                        break;
1183                    }
1184                    node_data = left;
1185                }
1186                Ordering::Greater => {
1187                    let right = unsafe { (*node_data).get_node() }.get_child(AvlDirection::Right);
1188                    if right.is_null() {
1189                        break;
1190                    }
1191                    node_data = right;
1192                }
1193            }
1194        }
1195        AvlSearchResult { node: nearest_node, direction: None, _phan: PhantomData }
1196    }
1197
1198    #[inline(always)]
1199    fn bottom_child_ref(&self, mut data: *const P::Target, dir: AvlDirection) -> *const P::Target {
1200        loop {
1201            let child = unsafe { (*data).get_node() }.get_child(dir);
1202            if !child.is_null() {
1203                data = child;
1204            } else {
1205                return data;
1206            }
1207        }
1208    }
1209
1210    /// return a iterator to get the reference
1211    ///
1212    /// NOTE: If you use the [Iterator] interface (for iteration), you only get &P::Target.
1213    ///
1214    /// you can use [AvlIter::next_ref()] to get &P.
1215    #[inline]
1216    pub fn iter(&self) -> AvlIter<'_, P, Tag> {
1217        let first_p = if !self.root.is_null() {
1218            Some(unsafe {
1219                NonNull::new_unchecked(
1220                    self.bottom_child_ref(self.root, AvlDirection::Left) as *mut P::Target
1221                )
1222            })
1223        } else {
1224            None
1225        };
1226        AvlIter::new(self, first_p, AvlDirection::Right)
1227    }
1228
1229    /// return a reversed iterator to get the reference.
1230    ///
1231    ///
1232    /// NOTE: If you use the [Iterator] interface (for iteration), you only get &P::Target.
1233    ///
1234    /// you can use [AvlIter::next_ref()] to get &P.
1235    #[inline]
1236    pub fn iter_rev(&self) -> AvlIter<'_, P, Tag> {
1237        let last_p = if !self.root.is_null() {
1238            Some(unsafe {
1239                NonNull::new_unchecked(
1240                    self.bottom_child_ref(self.root, AvlDirection::Right) as *mut P::Target
1241                )
1242            })
1243        } else {
1244            None
1245        };
1246        AvlIter::new(self, last_p, AvlDirection::Left)
1247    }
1248
1249    #[inline]
1250    pub fn next<'a>(&'a self, data: &'a P::Target) -> Option<&'a P::Target> {
1251        if let Some(p) = self.walk_dir(data.into(), AvlDirection::Right) {
1252            Some(unsafe { p.as_ref() })
1253        } else {
1254            None
1255        }
1256    }
1257
1258    #[inline]
1259    pub fn prev<'a>(&'a self, data: &'a P::Target) -> Option<&'a P::Target> {
1260        if let Some(p) = self.walk_dir(data.into(), AvlDirection::Left) {
1261            Some(unsafe { p.as_ref() })
1262        } else {
1263            None
1264        }
1265    }
1266
1267    #[inline]
1268    fn walk_dir(
1269        &self, mut data_ptr: NonNull<P::Target>, dir: AvlDirection,
1270    ) -> Option<NonNull<P::Target>> {
1271        let dir_inverse = dir.reverse();
1272        let node = unsafe { data_ptr.as_ref().get_node() };
1273        let temp = node.get_child(dir);
1274        if !temp.is_null() {
1275            unsafe {
1276                Some(NonNull::new_unchecked(
1277                    self.bottom_child_ref(temp, dir_inverse) as *mut P::Target
1278                ))
1279            }
1280        } else {
1281            let mut parent = node.parent;
1282            if parent.is_null() {
1283                return None;
1284            }
1285            loop {
1286                let pdir = self.parent_direction(data_ptr.as_ptr(), parent);
1287                if pdir == dir_inverse {
1288                    return Some(unsafe { NonNull::new_unchecked(parent as *mut P::Target) });
1289                }
1290                let data_ptr_raw = parent as *mut P::Target;
1291                parent = unsafe { (*parent).get_node() }.parent;
1292                if parent.is_null() {
1293                    return None;
1294                }
1295                unsafe {
1296                    data_ptr = NonNull::new_unchecked(data_ptr_raw);
1297                }
1298            }
1299        }
1300    }
1301
1302    #[inline]
1303    fn validate_node(&self, data: *const P::Target) {
1304        let node = unsafe { (*data).get_node() };
1305        let left = node.left;
1306        if !left.is_null() {
1307            assert!(unsafe { &*left }.cmp(unsafe { &*data }) != Ordering::Greater);
1308            assert_eq!(unsafe { (*left).get_node() }.get_parent(), data);
1309        }
1310        let right = node.right;
1311        if !right.is_null() {
1312            assert!(unsafe { &*right }.cmp(unsafe { &*data }) != Ordering::Less);
1313            assert_eq!(unsafe { (*right).get_node() }.get_parent(), data);
1314        }
1315    }
1316
1317    #[inline]
1318    pub fn first(&self) -> Option<&P::Target> {
1319        unsafe { return_end!(self, AvlDirection::Left).as_ref() }
1320    }
1321
1322    #[inline]
1323    pub fn last(&self) -> Option<&P::Target> {
1324        unsafe { return_end!(self, AvlDirection::Right).as_ref() }
1325    }
1326
1327    #[inline]
1328    pub fn nearest<'a>(
1329        &'a self, current: &AvlSearchResult<'a, P>, direction: AvlDirection,
1330    ) -> AvlSearchResult<'a, P> {
1331        if !current.node.is_null() {
1332            if current.direction.is_some() && current.direction != Some(direction) {
1333                return AvlSearchResult { node: current.node, direction: None, _phan: PhantomData };
1334            }
1335            if let Some(node) = self.walk_dir(
1336                unsafe { NonNull::new_unchecked(current.node as *mut P::Target) },
1337                direction,
1338            ) {
1339                return AvlSearchResult {
1340                    node: node.as_ptr(),
1341                    direction: None,
1342                    _phan: PhantomData,
1343                };
1344            }
1345        }
1346        AvlSearchResult::default()
1347    }
1348
1349    pub fn validate(&self) {
1350        let c = {
1351            #[cfg(feature = "std")]
1352            {
1353                ((self.len() + 10) as f32).log2() as usize
1354            }
1355            #[cfg(not(feature = "std"))]
1356            {
1357                100
1358            }
1359        };
1360        let mut stack: Vec<*const P::Target> = Vec::with_capacity(c);
1361        if self.root.is_null() {
1362            assert_eq!(self.count, 0);
1363            return;
1364        }
1365        let mut data = self.root;
1366        let mut visited = 0;
1367        loop {
1368            if !data.is_null() {
1369                let left = {
1370                    let node = unsafe { (*data).get_node() };
1371                    node.get_child(AvlDirection::Left)
1372                };
1373                if !left.is_null() {
1374                    stack.push(data);
1375                    data = left;
1376                    continue;
1377                }
1378                visited += 1;
1379                self.validate_node(data);
1380                data = unsafe { (*data).get_node() }.get_child(AvlDirection::Right);
1381            } else if !stack.is_empty() {
1382                let _data = stack.pop().unwrap();
1383                self.validate_node(_data);
1384                visited += 1;
1385                let node = unsafe { (*_data).get_node() };
1386                data = node.get_child(AvlDirection::Right);
1387            } else {
1388                break;
1389            }
1390        }
1391        assert_eq!(visited, self.count);
1392    }
1393}
1394
1395impl<P, Tag> Drop for AvlTree<P, Tag>
1396where
1397    P: Pointer,
1398    P::Target: AvlItem<Tag>,
1399{
1400    fn drop(&mut self) {
1401        if mem::needs_drop::<P>() {
1402            for _ in self.drain() {}
1403        }
1404    }
1405}
1406
1407impl<T, Tag> AvlTree<Arc<T>, Tag>
1408where
1409    T: AvlItem<Tag>,
1410{
1411    pub fn remove_ref(&mut self, node: &Arc<T>) {
1412        let p = Arc::as_ptr(node);
1413        unsafe { self.remove(p) };
1414        unsafe { drop(Arc::from_raw(p)) };
1415    }
1416}
1417
1418impl<T, Tag> AvlTree<Rc<T>, Tag>
1419where
1420    T: AvlItem<Tag>,
1421{
1422    pub fn remove_ref(&mut self, node: &Rc<T>) {
1423        let p = Rc::as_ptr(node);
1424        unsafe { self.remove(p) };
1425        unsafe { drop(Rc::from_raw(p)) };
1426    }
1427}