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