Skip to main content

fbl/
wavl_tree.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::ptr_traits::{ManagedPtr, PtrTraits};
6use crate::sentinel::{is_sentinel_ptr, make_sentinel, make_sentinel_null, valid_sentinel_ptr};
7use crate::size_tracker::{NonTrackingSize, SizeTracker};
8use crate::tag::DefaultObjectTag;
9use core::borrow::Borrow;
10use core::cell::UnsafeCell;
11use core::marker::PhantomData;
12use core::pin::Pin;
13use pin_init::{PinInit, pin_data, pin_init, pinned_drop};
14
15/// Trait defining an observer for a `WavlTree`.
16///
17/// Observers are used by the test framework to record the number of insert,
18/// erase, rank-promote, rank-demote, and rotation operations performed during
19/// usage. The default implementation does nothing and is optimized away.
20///
21/// Observers may also be used to maintain additional application-specific per-node
22/// invariants. For example, maintaining subtree min/max values is useful for multikey
23/// partition searching.
24///
25/// Note: Records of promotions and demotions are used by tests to demonstrate
26/// that the computational complexity of insert/erase rebalancing is amortized
27/// constant. Promotions and demotions which are side effects of the rotation
28/// phase of rebalancing are considered to be part of the cost of rotation and
29/// are not tallied in the overall promote/demote accounting.
30pub trait WavlTreeObserver {
31    /// The type pointed to by the tree pointers.
32    type Target;
33
34    /// Invoked on the newly inserted node before rebalancing.
35    fn record_insert(&self, _node: *mut Self::Target) {}
36
37    /// Invoked on the node to be inserted and each ancestor node while traversing
38    /// the tree to find the initial insertion point.
39    fn record_insert_traverse(&self, _node: *mut Self::Target, _ancestor: *mut Self::Target) {}
40
41    /// Invoked on the node to be inserted and the colliding node with the same
42    /// key, during an insert-or-find operation. This method is mutually exclusive
43    /// with `record_insert_replace`, only one or the other is invoked during an
44    /// insert operation.
45    fn record_insert_collision(&self, _node: *mut Self::Target, _collision: *mut Self::Target) {}
46
47    /// Invoked on an existing node and its replacement, before swapping the
48    /// replacement into the tree, during an insert-or-replace operation. This
49    /// method is mutually exclusive with `record_insert_collision`, only one or the
50    /// other is invoked during an insert operation.
51    fn record_insert_replace(&self, _node: *mut Self::Target, _replacement: *mut Self::Target) {}
52
53    /// Invoked after each promotion during post-insert rebalancing.
54    fn record_insert_promote(&self) {}
55
56    /// Invoked after a single rotation during post-insert rebalancing.
57    fn record_insert_rotation(&self) {}
58
59    /// Invoked after a double rotation during post-insert rebalancing.
60    fn record_insert_double_rotation(&self) {}
61
62    /// Invoked on the pivot node, its parent, children, and sibling before a
63    /// rotation, just before updating the pointers in the relevant nodes. The
64    /// chirality of the children and sibling is relative to the direction of
65    /// rotation. The direction of rotation can be determined by comparing these
66    /// arguments with the values returned by the left and right child properties
67    /// of the pivot or parent arguments.
68    ///
69    /// The following diagrams the relationship of the nodes in a left rotation:
70    ///
71    /// ```text
72    ///             pivot                          parent                             |
73    ///            /     \                         /    \                             |
74    ///        parent  rl_child  <-----------  sibling  pivot                         |
75    ///        /    \                                   /   \                         |
76    ///   sibling  lr_child                       lr_child  rl_child                  |
77    /// ```
78    ///
79    /// In a right rotation, all of the relationships are reflected.
80    fn record_rotation(
81        &self,
82        _pivot: *mut Self::Target,
83        _lr_child: *mut Self::Target,
84        _rl_child: *mut Self::Target,
85        _parent: *mut Self::Target,
86        _sibling: *mut Self::Target,
87    ) {
88    }
89
90    /// Invoked on the node to be erased and the node in the tree where the
91    /// augmented invariants become invalid, leading up to the root. Called just
92    /// after updating the pointers in the relevant nodes, but before rebalancing.
93    ///
94    /// The following diagrams the relationship of the erased and invalidated
95    /// nodes:
96    ///
97    /// ```text
98    ///        root                                                                   |
99    ///       /    \                                                                  |
100    ///      A      B    <---- Invalidated starting here on up to the root            |
101    ///     / \    / \                                                                |
102    ///    C   D  E   F  <---- Erased node                                            |
103    /// ```
104    ///
105    /// When the node to be erased has two children, it is first swapped with the
106    /// leftmost child of the righthand subtree. In this case the invalidated node
107    /// is the parent of the original leftmost child of the righthand subtree, as
108    /// this is the deepest node to change after erasure.
109    ///
110    /// ```text
111    ///        root                       root                                        |
112    ///       /    \                     /    \                                       |
113    ///      A      B                   A      B                                      |
114    ///     / \    / \                 / \    / \                                     |
115    ///    C   D  E   F  <--+         C   D  E   H    <---- Invalidated starting here |
116    ///              / \    | Swap              / \                                   |
117    ///             G   H <-+                  G   F  <---- Erased node               |
118    /// ```
119    fn record_erase(&self, _node: *mut Self::Target, _invalidated: *mut Self::Target) {}
120
121    /// Invoked after each demotion during post-erase rebalancing.
122    fn record_erase_demote(&self) {}
123
124    /// Invoked after each single rotation during post-erase rebalancing.
125    fn record_erase_rotation(&self) {}
126
127    /// Invoked after each double rotation during post-erase rebalancing.
128    fn record_erase_double_rotation(&self) {}
129
130    /// Invoked during testing to verify WAVL tree rank rules for a given node.
131    fn verify_rank_rule(
132        &self,
133        _node: *mut Self::Target,
134        _left_most: *mut Self::Target,
135        _right_most: *mut Self::Target,
136        _sentinel: *mut Self::Target,
137    ) {
138    }
139
140    /// Invoked during testing to verify tree balance properties given the tree size and depth.
141    fn verify_balance(&self, _size: usize, _depth: usize) {}
142}
143
144// `repr(transparent)` over a `PhantomData` so `WavlTree`s embedded in `#[repr(C)]` structs named
145// in `extern` signatures stay FFI-safe (`improper_ctypes`).
146#[repr(transparent)]
147pub struct DefaultWavlTreeObserver<T>(PhantomData<T>);
148impl<T> Default for DefaultWavlTreeObserver<T> {
149    fn default() -> Self {
150        Self(PhantomData)
151    }
152}
153impl<T> WavlTreeObserver for DefaultWavlTreeObserver<T> {
154    type Target = T;
155}
156
157/// Traits to implement to use `WavlTreeAugmentedInvariantObserver`.
158pub trait WavlTreeAugmentedInvariantObserverTraits {
159    /// The type of the node.
160    type Target;
161    /// The type of the invariant value. `PartialEq` lets the observer stop walking towards the
162    /// root as soon as a recomputed subtree value is unchanged.
163    type Value: Copy + PartialEq;
164
165    /// Returns the invariant value for the given node.
166    fn get_node_value(node: &Self::Target) -> Self::Value;
167
168    /// Returns the invariant value for the given node's subtree.
169    fn get_subtree_value(node: &Self::Target) -> Self::Value;
170
171    /// Combines subtree and node invariant values to produce a new subtree invariant value.
172    ///
173    /// Values are combined in in-order (left-to-right) sequence:
174    /// `left_subtree_value` is combined with `node_value`, and the result is combined
175    /// with `right_subtree_value`.
176    ///
177    /// The operation must be associative: `(a ∘ b) ∘ c == a ∘ (b ∘ c)`.
178    /// Non-commutative operations (such as string concatenation or sequence tracking)
179    /// are supported because child and node values are strictly combined in
180    /// in-order sequence across insertions, erasures, and rotations.
181    fn combine_values(a: Self::Value, b: Self::Value) -> Self::Value;
182
183    /// Sets the node's subtree invariant value.
184    fn set_subtree_value(node: &Self::Target, val: Self::Value);
185
186    /// Resets the node's subtree invariant value.
187    fn reset_subtree_value(node: &Self::Target);
188}
189
190/// A WAVL tree observer that maintains augmented invariants.
191// `repr(transparent)` over a `PhantomData` so `WavlTree`s embedded in `#[repr(C)]` structs named
192// in `extern` signatures stay FFI-safe (`improper_ctypes`).
193#[repr(transparent)]
194pub struct WavlTreeAugmentedInvariantObserver<
195    Tag,
196    Traits,
197    const ALLOW_FIND_COLLISION: bool = true,
198    const ALLOW_REPLACE_COLLISION: bool = true,
199> {
200    _phantom: PhantomData<(Tag, Traits)>,
201}
202
203impl<Tag, Traits, const ALLOW_FIND_COLLISION: bool, const ALLOW_REPLACE_COLLISION: bool> Default
204    for WavlTreeAugmentedInvariantObserver<
205        Tag,
206        Traits,
207        ALLOW_FIND_COLLISION,
208        ALLOW_REPLACE_COLLISION,
209    >
210{
211    fn default() -> Self {
212        Self { _phantom: PhantomData }
213    }
214}
215
216impl<Tag, Traits, const ALLOW_FIND_COLLISION: bool, const ALLOW_REPLACE_COLLISION: bool>
217    WavlTreeAugmentedInvariantObserver<Tag, Traits, ALLOW_FIND_COLLISION, ALLOW_REPLACE_COLLISION>
218where
219    Traits: WavlTreeAugmentedInvariantObserverTraits,
220    Traits::Target: WavlTreeContainable<Traits::Target, Tag>,
221{
222    /// Recomputes the subtree values from `current` up to the root.
223    ///
224    /// With `stop_when_unchanged`, the walk ends at the first node whose value does not change:
225    /// a subtree value is a pure function of the node's own value and its children's subtree
226    /// values, so once one ancestor is unchanged every ancestor above it is too. That holds only
227    /// if every node on the path still sits where its stored value was computed (true after an
228    /// insert or an in-place replace); an erase of a node with two children first swaps it with
229    /// its successor, whose stale stored value now sits above the invalidation point, so erase
230    /// must walk all the way to the root. In the common case of inserting a node that does not
231    /// change its parent's subtree value, the early-out stops after a single step.
232    ///
233    /// # Safety
234    ///
235    /// `current` must be null, the sentinel, or a valid pointer to a node linked into the tree
236    /// whose ancestor chain is intact.
237    unsafe fn recompute_until_root(
238        &self,
239        mut current: *mut Traits::Target,
240        stop_when_unchanged: bool,
241    ) {
242        while valid_sentinel_ptr(current) {
243            // SAFETY: `current` is non-null and non-sentinel, so by the caller's contract it is a
244            // valid node in the tree, as is every parent reached from it.
245            let current_ref = unsafe { &*current };
246            let node_value = Traits::get_node_value(current_ref);
247            let parent = current_ref.get_node().get_parent();
248            // SAFETY: As above.
249            let changed = unsafe { self.update_subtree_value(node_value, current) };
250            if stop_when_unchanged && !changed {
251                break;
252            }
253            current = parent;
254        }
255    }
256
257    /// Recomputes `node`'s subtree value from `value` and its children's subtree values, writing
258    /// it back only if it changed. Returns whether it changed.
259    ///
260    /// # Safety
261    ///
262    /// `node` must be a valid, non-null, non-sentinel pointer to a node linked into the tree.
263    unsafe fn update_subtree_value(
264        &self,
265        mut value: Traits::Value,
266        node: *mut Traits::Target,
267    ) -> bool {
268        // SAFETY: The caller guarantees `node` is a valid node in the tree.
269        let node_ref = unsafe { &*node };
270        let ns = node_ref.get_node();
271
272        let left = ns.get_left();
273        if valid_sentinel_ptr(left) {
274            let left_ref = unsafe { &*left };
275            let left_val = Traits::get_subtree_value(left_ref);
276            value = Traits::combine_values(left_val, value);
277        }
278
279        let right = ns.get_right();
280        if valid_sentinel_ptr(right) {
281            let right_ref = unsafe { &*right };
282            let right_val = Traits::get_subtree_value(right_ref);
283            value = Traits::combine_values(value, right_val);
284        }
285
286        if Traits::get_subtree_value(node_ref) == value {
287            return false;
288        }
289        Traits::set_subtree_value(node_ref, value);
290        true
291    }
292}
293
294#[allow(clippy::not_unsafe_ptr_arg_deref)]
295impl<Tag, Traits, const ALLOW_FIND_COLLISION: bool, const ALLOW_REPLACE_COLLISION: bool>
296    WavlTreeObserver
297    for WavlTreeAugmentedInvariantObserver<
298        Tag,
299        Traits,
300        ALLOW_FIND_COLLISION,
301        ALLOW_REPLACE_COLLISION,
302    >
303where
304    Traits: WavlTreeAugmentedInvariantObserverTraits,
305    Traits::Target: WavlTreeContainable<Traits::Target, Tag>,
306{
307    type Target = Traits::Target;
308
309    fn record_insert(&self, node: *mut Self::Target) {
310        // SAFETY: `WavlTree` passes a valid, non-null, non-sentinel node pointer that has just
311        // been linked into the tree.
312        let node_ref = unsafe { &*node };
313        let parent = node_ref.get_node().get_parent();
314        let val = Traits::get_node_value(node_ref);
315        Traits::set_subtree_value(node_ref, val);
316        if valid_sentinel_ptr(parent) {
317            // SAFETY: `parent` is a valid node in the tree (non-null, non-sentinel).
318            unsafe { self.recompute_until_root(parent, true) };
319        }
320    }
321
322    fn record_insert_traverse(&self, _node: *mut Self::Target, _ancestor: *mut Self::Target) {}
323
324    fn record_insert_collision(&self, _node: *mut Self::Target, _collision: *mut Self::Target) {
325        debug_assert!(ALLOW_FIND_COLLISION);
326    }
327
328    fn record_insert_replace(&self, node: *mut Self::Target, replacement: *mut Self::Target) {
329        debug_assert!(ALLOW_REPLACE_COLLISION);
330        // SAFETY: `WavlTree` passes valid, non-null, non-sentinel pointers for both the node being
331        // replaced (still linked into the tree) and its replacement.
332        let replacement_ref = unsafe { &*replacement };
333
334        // If `node`'s subtree value is unchanged by taking `replacement`'s value, so is every
335        // ancestor's, and the walk towards the root can be skipped entirely.
336        //
337        // SAFETY: `node` is still a valid node linked into the tree at this point.
338        let changed =
339            unsafe { self.update_subtree_value(Traits::get_node_value(replacement_ref), node) };
340        // SAFETY: As above.
341        let parent = unsafe { (*node).get_node().get_parent() };
342        if changed && valid_sentinel_ptr(parent) {
343            // SAFETY: `parent` is a valid node in the tree (non-null, non-sentinel).
344            unsafe {
345                self.recompute_until_root(parent, true);
346            }
347        }
348
349        // SAFETY: `WavlTree` passes a valid, non-null, non-sentinel node pointer.
350        let node_ref = unsafe { &*node };
351        Traits::set_subtree_value(replacement_ref, Traits::get_subtree_value(node_ref));
352        Traits::reset_subtree_value(node_ref);
353    }
354
355    fn record_rotation(
356        &self,
357        pivot: *mut Self::Target,
358        lr_child: *mut Self::Target,
359        _rl_child: *mut Self::Target,
360        parent: *mut Self::Target,
361        sibling: *mut Self::Target,
362    ) {
363        let parent_ref = unsafe { &*parent };
364        let parent_subtree_val = Traits::get_subtree_value(parent_ref);
365        let parent_ns = parent_ref.get_node();
366
367        // Determine rotation direction before links are updated.
368        // If pivot is parent's right child, it is a left rotation; otherwise a right rotation.
369        let is_left_rotation = parent_ns.get_right() == pivot;
370        let (left_child, right_child) = if is_left_rotation {
371            // Left rotation: sibling remains left child, lr_child becomes right child
372            (sibling, lr_child)
373        } else {
374            // Right rotation: lr_child becomes left child, sibling remains right child
375            (lr_child, sibling)
376        };
377
378        let mut parent_value = Traits::get_node_value(parent_ref);
379
380        if valid_sentinel_ptr(left_child) {
381            let left_ref = unsafe { &*left_child };
382            let left_val = Traits::get_subtree_value(left_ref);
383            parent_value = Traits::combine_values(left_val, parent_value);
384        }
385
386        if valid_sentinel_ptr(right_child) {
387            let right_ref = unsafe { &*right_child };
388            let right_val = Traits::get_subtree_value(right_ref);
389            parent_value = Traits::combine_values(parent_value, right_val);
390        }
391
392        // SAFETY: `WavlTree` passes a valid, non-null, non-sentinel pivot pointer.
393        let pivot_ref = unsafe { &*pivot };
394        Traits::set_subtree_value(pivot_ref, parent_subtree_val);
395
396        Traits::set_subtree_value(parent_ref, parent_value);
397    }
398
399    fn record_erase(&self, node: *mut Self::Target, invalidated: *mut Self::Target) {
400        // No early-out here: see `recompute_until_root` for why the successor swap makes it
401        // unsound on erase.
402        if valid_sentinel_ptr(invalidated) {
403            // SAFETY: `WavlTree` passes `invalidated` as the deepest node still linked into the
404            // tree whose subtree may have changed; it is non-null and non-sentinel here.
405            unsafe { self.recompute_until_root(invalidated, false) };
406        }
407        // SAFETY: `WavlTree` passes a valid, non-null, non-sentinel node pointer.
408        let node_ref = unsafe { &*node };
409        Traits::reset_subtree_value(node_ref);
410    }
411}
412
413/// Trait abstracting WAVL rank operations.
414pub trait WavlTreeRank: Copy {
415    /// The default rank value for a new node.
416    const DEFAULT: Self;
417    /// Returns the rank parity (true if odd, false if even).
418    fn rank_parity(rank: Self) -> bool;
419    /// Promotes the rank by 1.
420    fn promote_rank(rank: &mut Self);
421    /// Promotes the rank by 2.
422    fn double_promote_rank(rank: &mut Self);
423    /// Demotes the rank by 1.
424    fn demote_rank(rank: &mut Self);
425    /// Demotes the rank by 2.
426    fn double_demote_rank(rank: &mut Self);
427}
428
429impl WavlTreeRank for bool {
430    const DEFAULT: Self = false;
431    fn rank_parity(rank: Self) -> bool {
432        rank
433    }
434    fn promote_rank(rank: &mut Self) {
435        *rank = !*rank;
436    }
437    fn double_promote_rank(_rank: &mut Self) {} // no-op
438    fn demote_rank(rank: &mut Self) {
439        *rank = !*rank;
440    }
441    fn double_demote_rank(_rank: &mut Self) {} // no-op
442}
443
444impl WavlTreeRank for i32 {
445    const DEFAULT: Self = 0;
446    fn rank_parity(rank: Self) -> bool {
447        (rank & 1) != 0
448    }
449    fn promote_rank(rank: &mut Self) {
450        *rank += 1;
451    }
452    fn double_promote_rank(rank: &mut Self) {
453        *rank += 2;
454    }
455    fn demote_rank(rank: &mut Self) {
456        *rank -= 1;
457    }
458    fn double_demote_rank(rank: &mut Self) {
459        *rank -= 2;
460    }
461}
462
463/// A node in a Weak AVL (WAVL) Tree.
464#[repr(C)]
465pub struct WavlTreeNode<T, R: WavlTreeRank = bool> {
466    /// The parent element in the tree.
467    pub parent: UnsafeCell<*mut T>,
468    /// The left child element in the tree.
469    pub left: UnsafeCell<*mut T>,
470    /// The right child element in the tree.
471    pub right: UnsafeCell<*mut T>,
472    /// The integer rank of this node.
473    pub rank: UnsafeCell<R>,
474}
475
476impl<T, R: WavlTreeRank> WavlTreeNode<T, R> {
477    /// Creates a new, unlinked node.
478    pub const fn new() -> Self {
479        Self {
480            parent: UnsafeCell::new(core::ptr::null_mut()),
481            left: UnsafeCell::new(core::ptr::null_mut()),
482            right: UnsafeCell::new(core::ptr::null_mut()),
483            rank: UnsafeCell::new(R::DEFAULT),
484        }
485    }
486
487    /// Returns true if the node is currently in a tree.
488    pub fn in_container(&self) -> bool {
489        // SAFETY: Accessing parent pointer from UnsafeCell is safe because WavlTree coordinates
490        // exclusive mutations on containment states, ensuring no data races.
491        !unsafe { *self.parent.get() }.is_null()
492    }
493
494    fn get_parent(&self) -> *mut T {
495        // SAFETY: Accessing parent pointer from UnsafeCell is safe because it is only read sequentially
496        // or under logical exclusive containment borrow.
497        unsafe { *self.parent.get() }
498    }
499
500    fn set_parent(&self, parent: *mut T) {
501        // SAFETY: Mutating parent pointer in UnsafeCell is safe because the parent container holds
502        // exclusive mutable borrow of the containing tree structure.
503        unsafe {
504            *self.parent.get() = parent;
505        }
506    }
507
508    fn get_left(&self) -> *mut T {
509        // SAFETY: Accessing left pointer from UnsafeCell is safe because it is only read sequentially
510        // or under logical exclusive containment borrow.
511        unsafe { *self.left.get() }
512    }
513
514    fn set_left(&self, left: *mut T) {
515        // SAFETY: Mutating left pointer in UnsafeCell is safe because the parent container holds
516        // exclusive mutable borrow of the containing tree structure.
517        unsafe {
518            *self.left.get() = left;
519        }
520    }
521
522    fn get_right(&self) -> *mut T {
523        // SAFETY: Accessing right pointer from UnsafeCell is safe because it is only read sequentially
524        // or under logical exclusive containment borrow.
525        unsafe { *self.right.get() }
526    }
527
528    fn set_right(&self, right: *mut T) {
529        // SAFETY: Mutating right pointer in UnsafeCell is safe because the parent container holds
530        // exclusive mutable borrow of the containing tree structure.
531        unsafe {
532            *self.right.get() = right;
533        }
534    }
535
536    fn rank_parity(&self) -> bool {
537        // SAFETY: Reading rank from UnsafeCell is safe because it is only read sequentially or
538        // under logical exclusive container borrow.
539        unsafe { R::rank_parity(*self.rank.get()) }
540    }
541
542    /// Returns the rank value of this node.
543    pub fn rank(&self) -> R {
544        // SAFETY: Reading rank from UnsafeCell is safe because it is only read sequentially or
545        // under logical exclusive container borrow.
546        unsafe { *self.rank.get() }
547    }
548
549    fn promote_rank(&self) {
550        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
551        // exclusive mutable borrow of the containing tree structure.
552        unsafe {
553            R::promote_rank(&mut *self.rank.get());
554        }
555    }
556
557    fn double_promote_rank(&self) {
558        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
559        // exclusive mutable borrow of the containing tree structure.
560        unsafe {
561            R::double_promote_rank(&mut *self.rank.get());
562        }
563    }
564
565    fn demote_rank(&self) {
566        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
567        // exclusive mutable borrow of the containing tree structure.
568        unsafe {
569            R::demote_rank(&mut *self.rank.get());
570        }
571    }
572
573    fn double_demote_rank(&self) {
574        // SAFETY: Mutating rank in UnsafeCell is safe because the parent container holds
575        // exclusive mutable borrow of the containing tree structure.
576        unsafe {
577            R::double_demote_rank(&mut *self.rank.get());
578        }
579    }
580
581    /// Returns true if the node state invariants are currently valid.
582    pub fn is_valid(&self) -> bool {
583        let parent = self.get_parent();
584        let left = self.get_left();
585        let right = self.get_right();
586        !parent.is_null() || (parent.is_null() && left.is_null() && right.is_null())
587    }
588}
589
590impl<T, R: WavlTreeRank> core::fmt::Debug for WavlTreeNode<T, R> {
591    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
592        f.debug_struct("WavlTreeNode").field("in_container", &self.in_container()).finish()
593    }
594}
595
596impl<T, R: WavlTreeRank> Default for WavlTreeNode<T, R> {
597    fn default() -> Self {
598        Self::new()
599    }
600}
601
602impl<T, R: WavlTreeRank> Drop for WavlTreeNode<T, R> {
603    fn drop(&mut self) {
604        debug_assert!(!self.in_container(), "Object destroyed while still in container");
605    }
606}
607
608/// Trait that types must implement to be contained in a `WavlTree`.
609pub trait WavlTreeContainable<T, Tag = DefaultObjectTag> {
610    /// The rank type used by this node.
611    type Rank: WavlTreeRank;
612    /// Returns a reference to the tree node.
613    fn get_node(&self) -> &WavlTreeNode<T, Self::Rank>;
614}
615
616/// Trait that types must implement to expose a key for `WavlTree` sorting and lookup.
617pub trait WavlTreeKeyable<K: ?Sized> {
618    /// The type of key yielded by `get_key`, borrowing `K`.
619    ///
620    /// Implementations may return an owned/by-value key (e.g. `(u64, usize)` or `i32`)
621    /// or a borrowed/by-reference key (e.g. `&'a KeyStruct`).
622    type Key<'a>: Borrow<K>
623    where
624        Self: 'a;
625
626    /// Returns the key of this object.
627    fn get_key(&self) -> Self::Key<'_>;
628}
629
630#[allow(dead_code)]
631trait LrTraits {
632    type Inverse: LrTraits;
633
634    fn lr_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T;
635    fn rl_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T;
636
637    fn lr_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T;
638    fn rl_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T;
639
640    fn lr_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
641    where
642        P: PtrTraits,
643        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
644        K: Ord,
645        S: SizeTracker,
646        O: WavlTreeObserver<Target = P::Target>;
647
648    fn rl_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
649    where
650        P: PtrTraits,
651        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
652        K: Ord,
653        S: SizeTracker,
654        O: WavlTreeObserver<Target = P::Target>;
655
656    unsafe fn set_lr_most<K, P, Tag, S, O>(
657        tree: &mut WavlTree<K, P, Tag, S, O>,
658        val: *mut P::Target,
659    ) where
660        P: PtrTraits,
661        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
662        K: Ord,
663        S: SizeTracker,
664        O: WavlTreeObserver<Target = P::Target>;
665
666    unsafe fn set_rl_most<K, P, Tag, S, O>(
667        tree: &mut WavlTree<K, P, Tag, S, O>,
668        val: *mut P::Target,
669    ) where
670        P: PtrTraits,
671        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
672        K: Ord,
673        S: SizeTracker,
674        O: WavlTreeObserver<Target = P::Target>;
675}
676
677struct ForwardTraits;
678struct ReverseTraits;
679
680impl LrTraits for ForwardTraits {
681    type Inverse = ReverseTraits;
682
683    fn lr_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
684        ns.get_left()
685    }
686    fn rl_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
687        ns.get_right()
688    }
689
690    fn lr_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
691        ns.left.get()
692    }
693    fn rl_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
694        ns.right.get()
695    }
696
697    fn lr_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
698    where
699        P: PtrTraits,
700        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
701        K: Ord,
702        S: SizeTracker,
703        O: WavlTreeObserver<Target = P::Target>,
704    {
705        tree.left_most
706    }
707
708    fn rl_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
709    where
710        P: PtrTraits,
711        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
712        K: Ord,
713        S: SizeTracker,
714        O: WavlTreeObserver<Target = P::Target>,
715    {
716        tree.right_most
717    }
718
719    unsafe fn set_lr_most<K, P, Tag, S, O>(
720        tree: &mut WavlTree<K, P, Tag, S, O>,
721        val: *mut P::Target,
722    ) where
723        P: PtrTraits,
724        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
725        K: Ord,
726        S: SizeTracker,
727        O: WavlTreeObserver<Target = P::Target>,
728    {
729        tree.left_most = val;
730    }
731
732    unsafe fn set_rl_most<K, P, Tag, S, O>(
733        tree: &mut WavlTree<K, P, Tag, S, O>,
734        val: *mut P::Target,
735    ) where
736        P: PtrTraits,
737        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
738        K: Ord,
739        S: SizeTracker,
740        O: WavlTreeObserver<Target = P::Target>,
741    {
742        tree.right_most = val;
743    }
744}
745
746impl LrTraits for ReverseTraits {
747    type Inverse = ForwardTraits;
748
749    fn lr_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
750        ns.get_right()
751    }
752    fn rl_child<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut T {
753        ns.get_left()
754    }
755
756    fn lr_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
757        ns.right.get()
758    }
759    fn rl_child_ptr<T, R: WavlTreeRank>(ns: &WavlTreeNode<T, R>) -> *mut *mut T {
760        ns.left.get()
761    }
762
763    fn lr_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
764    where
765        P: PtrTraits,
766        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
767        K: Ord,
768        S: SizeTracker,
769        O: WavlTreeObserver<Target = P::Target>,
770    {
771        tree.right_most
772    }
773
774    fn rl_most<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>) -> *mut P::Target
775    where
776        P: PtrTraits,
777        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
778        K: Ord,
779        S: SizeTracker,
780        O: WavlTreeObserver<Target = P::Target>,
781    {
782        tree.left_most
783    }
784
785    unsafe fn set_lr_most<K, P, Tag, S, O>(
786        tree: &mut WavlTree<K, P, Tag, S, O>,
787        val: *mut P::Target,
788    ) where
789        P: PtrTraits,
790        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
791        K: Ord,
792        S: SizeTracker,
793        O: WavlTreeObserver<Target = P::Target>,
794    {
795        tree.right_most = val;
796    }
797
798    unsafe fn set_rl_most<K, P, Tag, S, O>(
799        tree: &mut WavlTree<K, P, Tag, S, O>,
800        val: *mut P::Target,
801    ) where
802        P: PtrTraits,
803        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
804        K: Ord,
805        S: SizeTracker,
806        O: WavlTreeObserver<Target = P::Target>,
807    {
808        tree.left_most = val;
809    }
810}
811
812/// A Weak AVL (WAVL) Tree associative container.
813///
814/// Implementation Notes:
815///
816/// WAVLTree<> is an implementation of a "Weak AVL" tree; a self
817/// balancing binary search tree whose rebalancing algorithm was
818/// originally described in
819///
820/// Bernhard Haeupler, Siddhartha Sen, and Robert E. Tarjan. 2015.
821/// Rank-Balanced Trees. ACM Trans. Algorithms 11, 4, Article 30 (June 2015), 26 pages.
822/// DOI=http://dx.doi.org/10.1145/2689412
823///
824/// See also
825/// https://en.wikipedia.org/wiki/WAVL_tree
826/// http://sidsen.azurewebsites.net/papers/rb-trees-talg.pdf
827///
828/// WAVLTree<>s, like HashTables, are associative containers and support all of
829/// the same key-centric operations (such as find() and insert_or_find()) that
830/// HashTables support.
831///
832/// Additionally, WAVLTree's are internally ordered by key (unlike HashTables
833/// which are un-ordered).  Iteration forwards or backwards runs in amortized
834/// constant time, but in O(log) time in an individual worst case.  Forward
835/// iteration will enumerate the elements in monotonically increasing order (as
836/// defined by the KeyTraits::LessThan operation).
837///
838/// Two additional operations are supported because of the ordered nature of a
839/// WAVLTree:
840/// upper_bound(key)        : Returns a cursor positioned at the first element (E) in the tree such that E.key > key.
841/// lower_bound(key)        : Returns a cursor positioned at the first element (E) in the tree such that E.key >= key.
842///
843/// The worst depth of a WAVL tree depends on whether or not the tree has ever
844/// been subject to erase operations.
845///
846/// ++ If the tree has seen only insert operations, the worst case depth of the
847///    tree is log_phi(N), where phi is the golden ratio.  This is the same bound
848///    as that of an AVL tree.
849/// ++ If the tree has seen erase operations in addition to insert operations,
850///    the worst case depth of the tree is 2*log_2(N).  This is the same bound as
851///    a Red-Black tree.
852///
853/// Insertion runs in O(log) time; finding the location takes O(log) time while
854/// post-insert rebalancing runs in amortized constant time.
855///
856/// Erase-by-key runs in O(log) time; finding the node to erase takes O(log) time
857/// while post-erase rebalancing runs in amortized constant time.
858///
859/// Because of the intrusive nature of the container, direct-erase operations
860/// (AKA, erase operations where the reference to the element to be erased is
861/// already known) run in amortized constant time.
862type TargetRank<P, Tag> =
863    <<P as PtrTraits>::Target as WavlTreeContainable<<P as PtrTraits>::Target, Tag>>::Rank;
864
865#[repr(C)]
866#[pin_data(PinnedDrop)]
867pub struct WavlTree<
868    K,
869    P,
870    Tag = DefaultObjectTag,
871    S = NonTrackingSize,
872    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
873> where
874    P: PtrTraits,
875    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
876    K: Ord,
877    S: SizeTracker,
878    O: WavlTreeObserver<Target = P::Target>,
879{
880    root: *mut P::Target,
881    left_most: *mut P::Target,
882    right_most: *mut P::Target,
883    size: S,
884    observer: O,
885    // Wrapped in `PhantomData` so the tree remains FFI-safe when embedded in `#[repr(C)]` structs
886    // named in `extern` signatures (`improper_ctypes` rejects a bare `PhantomPinned`, but ignores
887    // `PhantomData` fields).
888    #[pin]
889    _pin: core::marker::PhantomData<core::marker::PhantomPinned>,
890    _phantom: core::marker::PhantomData<(K, P, Tag)>,
891}
892
893impl<K, P, Tag, S, O> WavlTree<K, P, Tag, S, O>
894where
895    P: PtrTraits,
896    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
897    K: Ord,
898    S: SizeTracker,
899    O: WavlTreeObserver<Target = P::Target>,
900{
901    /// Creates a new, empty tree with a custom observer.
902    pub fn new_with_observer(observer: O) -> impl PinInit<Self, core::convert::Infallible> {
903        pin_init!(&this in Self {
904            root: core::ptr::null_mut(),
905            left_most: make_sentinel(this.as_ptr()),
906            right_most: make_sentinel(this.as_ptr()),
907            size: S::INIT,
908            observer,
909            _pin: core::marker::PhantomData,
910            _phantom: core::marker::PhantomData,
911        })
912    }
913
914    /// Creates a new, empty tree.
915    pub fn new() -> impl PinInit<Self, core::convert::Infallible>
916    where
917        O: Default,
918    {
919        Self::new_with_observer(O::default())
920    }
921
922    fn get_sentinel(&self) -> *mut P::Target {
923        make_sentinel(self as *const Self as *mut Self)
924    }
925
926    /// Returns a reference to the node state of `ptr`.
927    ///
928    /// # Safety
929    ///
930    /// The caller must ensure that `ptr` is a valid, aligned, and dereferenceable pointer
931    /// to an initialized `P::Target` object that is alive for the lifetime `'a`.
932    unsafe fn get_node_ref<'a>(
933        ptr: *mut P::Target,
934    ) -> &'a WavlTreeNode<P::Target, TargetRank<P, Tag>> {
935        // SAFETY: The caller guarantees that `ptr` is valid, aligned, and dereferenceable.
936        unsafe { &(*ptr) }.get_node()
937    }
938
939    /// Returns true if the tree is empty.
940    pub fn is_empty(&self) -> bool {
941        self.root.is_null()
942    }
943
944    /// Returns a reference to the first (smallest) element of the tree, or `None` if it is empty.
945    pub fn front(&self) -> Option<&P::Target> {
946        // SAFETY: `self.left_most` is a valid pointer to a node in the tree or the sentinel.
947        // If `self.is_empty()` is false, it is guaranteed to be a valid, dereferenceable
948        // pointer to a node.
949        if self.is_empty() { None } else { unsafe { Some(&*self.left_most) } }
950    }
951
952    /// Returns a reference to the last (largest) element of the tree, or `None` if it is empty.
953    pub fn back(&self) -> Option<&P::Target> {
954        // SAFETY: `self.right_most` is a valid pointer to a node in the tree or the sentinel.
955        // If `self.is_empty()` is false, it is guaranteed to be a valid, dereferenceable
956        // pointer to a node.
957        if self.is_empty() { None } else { unsafe { Some(&*self.right_most) } }
958    }
959
960    /// Returns a mutable pointer to the pointer linking `node` into the tree.
961    ///
962    /// # Safety
963    ///
964    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
965    /// to a node that is currently contained within this tree instance.
966    unsafe fn get_link_ptr_to_node(&mut self, node: *mut P::Target) -> *mut *mut P::Target {
967        debug_assert!(valid_sentinel_ptr(node));
968
969        // SAFETY: The caller guarantees that `node` is a valid pointer to a node currently in the tree.
970        let ns = unsafe { Self::get_node_ref(node) };
971        let parent = ns.get_parent();
972        if is_sentinel_ptr(parent) {
973            debug_assert_eq!(parent, self.get_sentinel());
974            debug_assert_eq!(self.root, node);
975            &mut self.root as *mut _
976        } else {
977            debug_assert!(!parent.is_null());
978            // SAFETY: `parent` is not a sentinel and is not null, so it must be a valid,
979            // dereferenceable pointer to a node in the tree.
980            let parent_ns = unsafe { Self::get_node_ref(parent) };
981            if parent_ns.get_left() == node {
982                parent_ns.left.get()
983            } else {
984                debug_assert_eq!(parent_ns.get_right(), node);
985                parent_ns.right.get()
986            }
987        }
988    }
989
990    /// Performs a tree rotation in the direction specified by `LR`.
991    ///
992    /// # Safety
993    ///
994    /// The caller must ensure that `node` and `parent` are valid, aligned, and dereferenceable
995    /// pointers to nodes currently contained within this tree instance, and that `node` is
996    /// a child of `parent` in the direction specified by `LR::Inverse`.
997    unsafe fn rotate_lr<LR: LrTraits>(&mut self, node: *mut P::Target, parent: *mut P::Target) {
998        // SAFETY: The caller guarantees that `node` and `parent` are valid pointers to nodes
999        // currently in the tree. The structural modifications (rotations) correctly permute the
1000        // parent/child links while maintaining BST structural validity.
1001        unsafe {
1002            debug_assert!(valid_sentinel_ptr(node));
1003            debug_assert!(valid_sentinel_ptr(parent));
1004
1005            let x = node;
1006            let z = parent;
1007
1008            let x_ns = Self::get_node_ref(x);
1009            let z_ns = Self::get_node_ref(z);
1010
1011            debug_assert_eq!(LR::rl_child(z_ns), x);
1012
1013            let x_link = LR::rl_child_ptr(z_ns);
1014            let y_link = LR::lr_child_ptr(x_ns);
1015            let z_link = self.get_link_ptr_to_node(z);
1016
1017            let g = z_ns.get_parent();
1018            let y = *y_link;
1019
1020            debug_assert!(!is_sentinel_ptr(y));
1021
1022            // Permute the downstream links.
1023            self.observer.record_rotation(x, y, LR::rl_child(x_ns), z, LR::lr_child(z_ns));
1024            let tmp = *x_link;
1025            *x_link = *y_link;
1026            *y_link = *z_link;
1027            *z_link = tmp;
1028
1029            // Update parent pointers.
1030            x_ns.set_parent(g);
1031            z_ns.set_parent(x);
1032            if !y.is_null() {
1033                Self::get_node_ref(y).set_parent(z);
1034            }
1035        }
1036    }
1037
1038    /// Performs post-insertion balancing fixups.
1039    ///
1040    /// # Safety
1041    ///
1042    /// The caller must ensure that `node` and `parent` are valid, aligned, and dereferenceable
1043    /// pointers to nodes currently contained within this tree instance, and that `node` is
1044    /// a child of `parent` in the direction specified by `LR`.
1045    unsafe fn post_insert_fixup_lr<LR: LrTraits>(
1046        &mut self,
1047        node: *mut P::Target,
1048        parent: *mut P::Target,
1049    ) {
1050        type RL<LR> = <LR as LrTraits>::Inverse;
1051
1052        // SAFETY: The caller guarantees `node` and `parent` are valid pointers to nodes currently
1053        // in the tree. The subsequent operations (including rotations and rank updates) correctly
1054        // rebalance the tree according to WAVL insertion balance algorithms.
1055        unsafe {
1056            debug_assert!(valid_sentinel_ptr(node));
1057            debug_assert!(valid_sentinel_ptr(parent));
1058
1059            let node_ns = Self::get_node_ref(node);
1060            let parent_ns = Self::get_node_ref(parent);
1061
1062            debug_assert_eq!(LR::lr_child(parent_ns), node);
1063
1064            let rl_child = LR::rl_child(node_ns);
1065            let rl_child_ns = if valid_sentinel_ptr(rl_child) {
1066                Some(Self::get_node_ref(rl_child))
1067            } else {
1068                None
1069            };
1070
1071            if let Some(rl_child_ns) = rl_child_ns
1072                && rl_child_ns.rank_parity() != node_ns.rank_parity()
1073            {
1074                // Case #1: double rotation.
1075                self.rotate_lr::<LR>(rl_child, node);
1076                self.rotate_lr::<RL<LR>>(rl_child, parent);
1077
1078                rl_child_ns.promote_rank();
1079                node_ns.demote_rank();
1080                parent_ns.demote_rank();
1081                self.observer.record_insert_double_rotation();
1082            } else {
1083                // Case #2: single rotation.
1084                self.rotate_lr::<RL<LR>>(node, parent);
1085                parent_ns.demote_rank();
1086                self.observer.record_insert_rotation();
1087            }
1088        }
1089    }
1090
1091    /// Rebalances the tree after an element is inserted.
1092    ///
1093    /// # Safety
1094    ///
1095    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
1096    /// to a node that has just been inserted into this tree instance, and that the tree
1097    /// is structurally valid except for potential balance violations at `node` and its ancestors.
1098    unsafe fn balance_post_insert(&mut self, mut node: *mut P::Target) {
1099        // SAFETY: The caller guarantees `node` is a valid pointer to a node in the tree.
1100        // The loop climbs the tree, updating ranks and performing rotations as needed, maintaining
1101        // tree integrity.
1102        unsafe {
1103            let mut node_ns = Self::get_node_ref(node);
1104            debug_assert!(valid_sentinel_ptr(node_ns.get_parent()));
1105
1106            let mut parent = node_ns.get_parent();
1107            let mut parent_ns = Self::get_node_ref(parent);
1108
1109            if valid_sentinel_ptr(parent_ns.get_left()) && valid_sentinel_ptr(parent_ns.get_right())
1110            {
1111                return;
1112            }
1113
1114            let mut node_parity;
1115            let mut parent_parity;
1116            let mut sibling_parity;
1117            let mut is_left_child;
1118
1119            loop {
1120                // Promote.
1121                parent_ns.promote_rank();
1122                self.observer.record_insert_promote();
1123
1124                // Climb.
1125                node = parent;
1126                node_ns = Self::get_node_ref(node);
1127                parent = node_ns.get_parent();
1128
1129                if !valid_sentinel_ptr(parent) {
1130                    return;
1131                }
1132
1133                parent_ns = Self::get_node_ref(parent);
1134                is_left_child = parent_ns.get_left() == node;
1135                if is_left_child {
1136                    sibling_parity = if valid_sentinel_ptr(parent_ns.get_right()) {
1137                        Self::get_node_ref(parent_ns.get_right()).rank_parity()
1138                    } else {
1139                        true
1140                    };
1141                } else {
1142                    debug_assert_eq!(parent_ns.get_right(), node);
1143                    sibling_parity = if valid_sentinel_ptr(parent_ns.get_left()) {
1144                        Self::get_node_ref(parent_ns.get_left()).rank_parity()
1145                    } else {
1146                        true
1147                    };
1148                }
1149
1150                node_parity = node_ns.rank_parity();
1151                parent_parity = parent_ns.rank_parity();
1152
1153                if !((!node_parity && !parent_parity && sibling_parity)
1154                    || (node_parity && parent_parity && !sibling_parity))
1155                {
1156                    break;
1157                }
1158            }
1159
1160            if (node_parity != parent_parity) || (node_parity != sibling_parity) {
1161                return;
1162            }
1163
1164            if is_left_child {
1165                self.post_insert_fixup_lr::<ForwardTraits>(node, parent);
1166            } else {
1167                self.post_insert_fixup_lr::<ReverseTraits>(node, parent);
1168            }
1169        }
1170    }
1171
1172    /// Performs balance adjustments for a "2-2 leaf" node after erasure.
1173    ///
1174    /// # Safety
1175    ///
1176    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
1177    /// to a node currently contained within this tree instance, and that the tree is structurally
1178    /// valid except for potential balance violations after an erasure at `node`.
1179    unsafe fn balance_post_erase_fix_22_leaf(&mut self, node: *mut P::Target) {
1180        // SAFETY: The caller guarantees `node` is a valid pointer to a node in the tree.
1181        // The function safely demotes the rank and propagates rebalancing up the tree.
1182        unsafe {
1183            debug_assert!(valid_sentinel_ptr(node));
1184
1185            let ns = Self::get_node_ref(node);
1186            if !ns.rank_parity()
1187                || valid_sentinel_ptr(ns.get_left())
1188                || valid_sentinel_ptr(ns.get_right())
1189            {
1190                return;
1191            }
1192
1193            ns.demote_rank();
1194            self.observer.record_erase_demote();
1195
1196            let parent = ns.get_parent();
1197            debug_assert!(!parent.is_null());
1198            if is_sentinel_ptr(parent) {
1199                return;
1200            }
1201
1202            let parent_ns = Self::get_node_ref(parent);
1203            let is_left_child = parent_ns.get_left() == node;
1204            debug_assert!(is_left_child || parent_ns.get_right() == node);
1205
1206            if is_left_child {
1207                self.balance_post_erase_fix_lr_3_child::<ForwardTraits>(parent);
1208            } else {
1209                self.balance_post_erase_fix_lr_3_child::<ReverseTraits>(parent);
1210            }
1211        }
1212    }
1213
1214    /// Rebalances the tree after an element is erased, resolving violations of the 3-child rule.
1215    ///
1216    /// # Safety
1217    ///
1218    /// The caller must ensure that `node` is a valid, aligned, and dereferenceable pointer
1219    /// to a node currently contained within this tree instance, and that `node` is the parent
1220    /// of a subtree that has just seen an erasure and violates the 3-child balance rule.
1221    unsafe fn balance_post_erase_fix_lr_3_child<LR: LrTraits>(&mut self, node: *mut P::Target) {
1222        type RL<LR> = <LR as LrTraits>::Inverse;
1223        // SAFETY: The caller guarantees `node` is a valid pointer to a node in the tree.
1224        // The loop walks up the tree performing rank adjustments and triggers rotations as required
1225        // by the WAVL erase balancing algorithms.
1226        unsafe {
1227            debug_assert!(valid_sentinel_ptr(node));
1228
1229            let mut z = node;
1230            let mut z_ns = Self::get_node_ref(z);
1231            let mut x = LR::lr_child(z_ns);
1232
1233            if valid_sentinel_ptr(x) != z_ns.rank_parity() {
1234                return;
1235            }
1236
1237            let mut x_is_lr_child = true;
1238            let mut y = LR::rl_child(z_ns);
1239
1240            loop {
1241                debug_assert!(valid_sentinel_ptr(y));
1242
1243                let y_ns = Self::get_node_ref(y);
1244                let y_is_2_child = y_ns.rank_parity() == z_ns.rank_parity();
1245
1246                if !y_is_2_child {
1247                    let y_is_22_node = if y_ns.rank_parity() {
1248                        (!valid_sentinel_ptr(y_ns.get_left())
1249                            || Self::get_node_ref(y_ns.get_left()).rank_parity())
1250                            && (!valid_sentinel_ptr(y_ns.get_right())
1251                                || Self::get_node_ref(y_ns.get_right()).rank_parity())
1252                    } else {
1253                        valid_sentinel_ptr(y_ns.get_left())
1254                            && valid_sentinel_ptr(y_ns.get_right())
1255                            && !Self::get_node_ref(y_ns.get_left()).rank_parity()
1256                            && !Self::get_node_ref(y_ns.get_right()).rank_parity()
1257                    };
1258
1259                    if !y_is_22_node {
1260                        break;
1261                    }
1262                }
1263
1264                z_ns.demote_rank();
1265                self.observer.record_erase_demote();
1266                if !y_is_2_child {
1267                    y_ns.demote_rank();
1268                    self.observer.record_erase_demote();
1269                }
1270
1271                if !valid_sentinel_ptr(z_ns.get_parent()) {
1272                    return;
1273                }
1274
1275                let x_rank_parity = z_ns.rank_parity();
1276                x = z;
1277                z = z_ns.get_parent();
1278                z_ns = Self::get_node_ref(z);
1279
1280                if z_ns.rank_parity() == x_rank_parity {
1281                    return;
1282                }
1283
1284                x_is_lr_child = LR::lr_child(z_ns) == x;
1285                y = if x_is_lr_child { LR::rl_child(z_ns) } else { LR::lr_child(z_ns) };
1286            }
1287
1288            if x_is_lr_child {
1289                self.balance_post_erase_do_rotations::<LR>(y, z);
1290            } else {
1291                self.balance_post_erase_do_rotations::<RL<LR>>(y, z);
1292            }
1293        }
1294    }
1295
1296    /// Performs necessary rotations during post-erase rebalancing.
1297    ///
1298    /// # Safety
1299    ///
1300    /// The caller must ensure that `y` and `z` are valid, aligned, and dereferenceable
1301    /// pointers to nodes currently contained within this tree instance, and that `y` is the
1302    /// right child of `z` in the direction specified by `LR`.
1303    unsafe fn balance_post_erase_do_rotations<LR: LrTraits>(
1304        &mut self,
1305        y: *mut P::Target,
1306        z: *mut P::Target,
1307    ) {
1308        type RL<LR> = <LR as LrTraits>::Inverse;
1309        // SAFETY: The caller guarantees `y` and `z` are valid pointers to nodes in the tree.
1310        // The rotations correctly rebalance the tree at `z` and update ranks accordingly.
1311        unsafe {
1312            debug_assert!(valid_sentinel_ptr(y));
1313            debug_assert!(valid_sentinel_ptr(z));
1314
1315            let y_ns = Self::get_node_ref(y);
1316            let z_ns = Self::get_node_ref(z);
1317
1318            let w = LR::rl_child(y_ns);
1319            let w_rank_parity =
1320                if valid_sentinel_ptr(w) { Self::get_node_ref(w).rank_parity() } else { true };
1321
1322            if y_ns.rank_parity() != w_rank_parity {
1323                self.rotate_lr::<LR>(y, z);
1324                y_ns.promote_rank();
1325
1326                if !valid_sentinel_ptr(z_ns.get_left()) && !valid_sentinel_ptr(z_ns.get_right()) {
1327                    z_ns.double_demote_rank();
1328                } else {
1329                    z_ns.demote_rank();
1330                }
1331                self.observer.record_erase_rotation();
1332            } else {
1333                let v = LR::lr_child(y_ns);
1334                debug_assert!(valid_sentinel_ptr(v));
1335                let v_ns = Self::get_node_ref(v);
1336                debug_assert_ne!(v_ns.rank_parity(), y_ns.rank_parity());
1337
1338                self.rotate_lr::<RL<LR>>(v, y);
1339                self.rotate_lr::<LR>(v, z);
1340
1341                v_ns.double_promote_rank();
1342                y_ns.demote_rank();
1343                z_ns.double_demote_rank();
1344                self.observer.record_erase_double_rotation();
1345            }
1346        }
1347    }
1348
1349    /// Promotes the single child of `node` (in direction `LR`) to take `node`'s place in the tree.
1350    ///
1351    /// # Safety
1352    ///
1353    /// - `owner` must be a valid, aligned, dereferenceable pointer to a `*mut P::Target`.
1354    /// - `*owner` must be `null_mut()`.
1355    /// - `node` must be a valid, aligned, dereferenceable pointer to a node currently in the tree.
1356    /// - `node` must have exactly one child in the direction specified by `LR` (which must be
1357    ///   a valid non-null, non-sentinel node), and must NOT have a valid child in the opposite direction.
1358    unsafe fn promote_lr_child<LR: LrTraits>(
1359        &mut self,
1360        owner: *mut *mut P::Target,
1361        node: *mut P::Target,
1362    ) {
1363        // SAFETY: The caller must guarantee that `owner` is a valid, aligned, dereferenceable pointer
1364        // to `*mut P::Target` containing `null_mut()`, that `node` is a valid node in the tree,
1365        // and that the node has exactly one child in the `LR` direction to promote.
1366        unsafe {
1367            debug_assert!((*owner).is_null());
1368            debug_assert!(valid_sentinel_ptr(node));
1369
1370            let ns = Self::get_node_ref(node);
1371            let lr_child_ptr = LR::lr_child_ptr(ns);
1372            let rl_child_ptr = LR::rl_child_ptr(ns);
1373
1374            debug_assert!(valid_sentinel_ptr(*lr_child_ptr) && !valid_sentinel_ptr(*rl_child_ptr));
1375
1376            *owner = *lr_child_ptr;
1377            *lr_child_ptr = core::ptr::null_mut();
1378            Self::get_node_ref(*owner).set_parent(ns.get_parent());
1379
1380            let rl_most = LR::rl_most(self);
1381            debug_assert_eq!(rl_most == node, is_sentinel_ptr(*rl_child_ptr));
1382
1383            if is_sentinel_ptr(*rl_child_ptr) {
1384                let mut replacement = *owner;
1385                let mut next_rl_child_ptr;
1386
1387                loop {
1388                    let replacement_ns = Self::get_node_ref(replacement);
1389                    next_rl_child_ptr = LR::rl_child_ptr(replacement_ns);
1390
1391                    debug_assert!(!is_sentinel_ptr(*next_rl_child_ptr));
1392                    if (*next_rl_child_ptr).is_null() {
1393                        break;
1394                    }
1395                    replacement = *next_rl_child_ptr;
1396                }
1397
1398                LR::set_rl_most(self, replacement);
1399                *next_rl_child_ptr = self.get_sentinel();
1400                *rl_child_ptr = core::ptr::null_mut();
1401            }
1402
1403            ns.set_parent(core::ptr::null_mut());
1404            debug_assert!(ns.get_left().is_null());
1405            debug_assert!(ns.get_right().is_null());
1406        }
1407    }
1408
1409    /// Physically swaps the position of `node1` (pointed to by `ptr_ref1`) with `node2`
1410    /// (pointed to by `ptr_ref2`) in the tree's pointer structure.
1411    ///
1412    /// E.g. `node2` must be the leftmost descendant of the right child of `node1`.
1413    ///
1414    /// Returns the pointer to the slot originally containing `node2` (which now contains `node1`).
1415    ///
1416    /// # Safety
1417    ///
1418    /// - `ptr_ref1` must be a valid, aligned, dereferenceable pointer to `*mut P::Target`
1419    ///   which contains a valid, aligned, dereferenceable pointer to `node1`.
1420    /// - `ptr_ref2` must be a valid, aligned, dereferenceable pointer to `*mut P::Target`
1421    ///   which contains a valid, aligned, dereferenceable pointer to `node2`.
1422    /// - `node2` must be a descendant of `node1`'s right subtree.
1423    /// - Both `node1` and `node2` must reside within the same tree.
1424    unsafe fn swap_with_right_descendant(
1425        &mut self,
1426        ptr_ref1: *mut *mut P::Target,
1427        ptr_ref2: *mut *mut P::Target,
1428    ) -> *mut *mut P::Target {
1429        // SAFETY: The caller must guarantee that `ptr_ref1` and `ptr_ref2` are valid, aligned
1430        // pointers pointing to valid nodes in the tree, and that `node2` is a descendant in the
1431        // right subtree of `node1`. This method performs structural pointer manipulation to swap
1432        // the nodes physically, preserving local tree structure.
1433        unsafe {
1434            let node1 = *ptr_ref1;
1435            let node2 = *ptr_ref2;
1436
1437            let ns1 = Self::get_node_ref(node1);
1438            let ns2 = Self::get_node_ref(node2);
1439
1440            if ns1.get_right().is_null() {
1441                panic!("node1 right is NULL inside swap");
1442            }
1443
1444            let ns1_lp = if valid_sentinel_ptr(ns1.get_left()) {
1445                Self::get_node_ref(ns1.get_left()).parent.get()
1446            } else {
1447                core::ptr::null_mut()
1448            };
1449
1450            let ns2_lp = if valid_sentinel_ptr(ns2.get_left()) {
1451                Self::get_node_ref(ns2.get_left()).parent.get()
1452            } else {
1453                core::ptr::null_mut()
1454            };
1455
1456            let ns2_rp = if valid_sentinel_ptr(ns2.get_right()) {
1457                Self::get_node_ref(ns2.get_right()).parent.get()
1458            } else {
1459                core::ptr::null_mut()
1460            };
1461
1462            let r1 = ns1.get_right();
1463            if !valid_sentinel_ptr(r1) {
1464                if r1.is_null() {
1465                    panic!("ns1.get_right() is NULL");
1466                } else if is_sentinel_ptr(r1) {
1467                    panic!("ns1.get_right() is SENTINEL");
1468                } else {
1469                    panic!("ns1.get_right() is OTHER INVALID");
1470                }
1471            }
1472            let ns1_rp = Self::get_node_ref(ns1.get_right()).parent.get();
1473
1474            if node1 == self.left_most {
1475                self.left_most = node2;
1476            }
1477            if node2 == self.right_most {
1478                self.right_most = node1;
1479            }
1480
1481            // Swap parent.
1482            let parent_tmp = ns1.get_parent();
1483            ns1.set_parent(ns2.get_parent());
1484            ns2.set_parent(parent_tmp);
1485
1486            // Swap left.
1487            let left_tmp = ns1.get_left();
1488            ns1.set_left(ns2.get_left());
1489            ns2.set_left(left_tmp);
1490
1491            // Swap right.
1492            let right_tmp = ns1.get_right();
1493            ns1.set_right(ns2.get_right());
1494            ns2.set_right(right_tmp);
1495
1496            // Swap rank.
1497            let rank_tmp = *ns1.rank.get();
1498            *ns1.rank.get() = *ns2.rank.get();
1499            *ns2.rank.get() = rank_tmp;
1500
1501            if !ns1_lp.is_null() {
1502                *ns1_lp = node2;
1503            }
1504            if !ns2_lp.is_null() {
1505                *ns2_lp = node1;
1506            }
1507            if !ns2_rp.is_null() {
1508                *ns2_rp = node1;
1509            }
1510
1511            if ptr_ref2 != ns1.right.get() {
1512                #[allow(clippy::swap_ptr_to_ref)]
1513                core::mem::swap(&mut *ptr_ref1, &mut *ptr_ref2);
1514                *ns1_rp = node2;
1515                ptr_ref2
1516            } else {
1517                debug_assert_eq!(*ns1.parent.get(), node1);
1518                debug_assert_eq!(*ns2.right.get(), node2);
1519                #[allow(clippy::swap_ptr_to_ref)]
1520                core::mem::swap(&mut *ptr_ref1, &mut *ns2.right.get());
1521                *ns1.parent.get() = node2;
1522                ns2.right.get()
1523            }
1524        }
1525    }
1526
1527    /// Inserts a new node `ptr` into the WAVL tree.
1528    ///
1529    /// If a node with an identical key already exists, does not insert it, stores the colliding node's
1530    /// pointer in `collision`, and returns the original `ptr` as `Err(ptr)`.
1531    ///
1532    /// # Safety
1533    ///
1534    /// - `ptr` must wrap a valid, properly aligned, dereferenceable node.
1535    /// - The node must NOT be currently contained in this or any other intrusive container.
1536    /// - `collision` must be a valid, aligned, dereferenceable pointer to `*mut P::Target`.
1537    unsafe fn internal_insert(&mut self, ptr: P, collision: &mut *mut P::Target) -> Result<(), P> {
1538        // SAFETY: The caller guarantees that `ptr` represents a valid, unlinked node, and that
1539        // `collision` is a valid slot. Dereferencing pointers and mutating the parent/child links
1540        // preserves tree structure.
1541        unsafe {
1542            let raw = P::into_raw(ptr);
1543            debug_assert!(!raw.is_null());
1544
1545            let ns = Self::get_node_ref(raw);
1546            debug_assert!(ns.is_valid() && !ns.in_container());
1547
1548            *ns.rank.get() = <TargetRank<P, Tag>>::DEFAULT;
1549
1550            if self.root.is_null() {
1551                ns.set_parent(self.get_sentinel());
1552                ns.set_left(self.get_sentinel());
1553                ns.set_right(self.get_sentinel());
1554
1555                debug_assert!(is_sentinel_ptr(self.left_most) && is_sentinel_ptr(self.right_most));
1556                self.left_most = raw;
1557                self.right_most = raw;
1558
1559                self.root = raw;
1560                self.size.increment();
1561                self.observer.record_insert(raw);
1562                return Ok(());
1563            }
1564
1565            let key = (*raw).get_key();
1566            let key_borrow = key.borrow();
1567            let mut is_left_most = true;
1568            let mut is_right_most = true;
1569            let mut parent = self.root;
1570            let mut owner: *mut *mut P::Target;
1571
1572            loop {
1573                let parent_key = (*parent).get_key();
1574                let parent_key_borrow = parent_key.borrow();
1575                self.observer.record_insert_traverse(raw, parent);
1576
1577                if key_borrow == parent_key_borrow {
1578                    *collision = parent;
1579                    self.observer.record_insert_collision(raw, parent);
1580                    return Err(P::from_raw(raw));
1581                }
1582
1583                let parent_ns = Self::get_node_ref(parent);
1584
1585                if key_borrow < parent_key_borrow {
1586                    owner = parent_ns.left.get();
1587                    is_right_most = false;
1588                } else {
1589                    owner = parent_ns.right.get();
1590                    is_left_most = false;
1591                }
1592
1593                if !valid_sentinel_ptr(*owner) {
1594                    break;
1595                }
1596
1597                parent = *owner;
1598            }
1599
1600            debug_assert!(!is_left_most || !is_right_most);
1601
1602            if is_right_most {
1603                debug_assert!(is_sentinel_ptr(*owner));
1604                ns.set_right(self.get_sentinel());
1605                self.right_most = raw;
1606            } else if is_left_most {
1607                debug_assert!(is_sentinel_ptr(*owner));
1608                ns.set_left(self.get_sentinel());
1609                self.left_most = raw;
1610            }
1611
1612            debug_assert!(!valid_sentinel_ptr(*owner));
1613            ns.set_parent(parent);
1614
1615            *owner = raw;
1616            self.size.increment();
1617            self.observer.record_insert(raw);
1618
1619            self.balance_post_insert(*owner);
1620            Ok(())
1621        }
1622    }
1623
1624    /// Removes the node `ptr` from the WAVL tree, rebalancing if necessary.
1625    ///
1626    /// Returns the node wrapped in `P` if it was successfully erased and returned.
1627    ///
1628    /// # Safety
1629    ///
1630    /// - `ptr` must be a valid, properly aligned, dereferenceable raw pointer to a node.
1631    /// - If the node is not null or sentinel, it MUST be currently contained within this tree.
1632    unsafe fn internal_erase(&mut self, ptr: *mut P::Target) -> Option<P> {
1633        // SAFETY: The caller guarantees that `ptr` points to a valid node belonging to this tree.
1634        // Removing it involves swapping it out structurally, repairing BST/WAVL invariants,
1635        // and reclaiming ownership via `P::from_raw`.
1636        unsafe {
1637            if !valid_sentinel_ptr(ptr) {
1638                return None;
1639            }
1640
1641            let ns = Self::get_node_ref(ptr);
1642            let mut owner = self.get_link_ptr_to_node(ptr);
1643            debug_assert_eq!(*owner, ptr);
1644
1645            if valid_sentinel_ptr(ns.get_left()) && valid_sentinel_ptr(ns.get_right()) {
1646                let mut new_owner = ns.right.get();
1647                let mut new_ns = Self::get_node_ref(ns.get_right());
1648
1649                while !new_ns.get_left().is_null() {
1650                    debug_assert!(!is_sentinel_ptr(new_ns.get_left()));
1651                    new_owner = new_ns.left.get();
1652                    new_ns = Self::get_node_ref(*new_owner);
1653                }
1654
1655                owner = self.swap_with_right_descendant(owner, new_owner);
1656                debug_assert_eq!(*owner, ptr);
1657            }
1658
1659            let parent = ns.get_parent();
1660            debug_assert!(!parent.is_null());
1661            let (was_one_child, was_left_child) = if !is_sentinel_ptr(parent) {
1662                let parent_ns = Self::get_node_ref(parent);
1663                (ns.rank_parity() != parent_ns.rank_parity(), parent_ns.left.get() == owner)
1664            } else {
1665                (false, false)
1666            };
1667
1668            *owner = core::ptr::null_mut();
1669
1670            let target = ptr;
1671            if valid_sentinel_ptr(ns.get_left()) {
1672                self.promote_lr_child::<ForwardTraits>(owner, target);
1673            } else if valid_sentinel_ptr(ns.get_right()) {
1674                self.promote_lr_child::<ReverseTraits>(owner, target);
1675            } else {
1676                debug_assert_eq!(is_sentinel_ptr(ns.get_left()), self.left_most == target);
1677                debug_assert_eq!(is_sentinel_ptr(ns.get_right()), self.right_most == target);
1678
1679                if is_sentinel_ptr(ns.get_left()) {
1680                    if is_sentinel_ptr(ns.get_right()) {
1681                        if S::IS_TRACKING {
1682                            debug_assert_eq!(self.size.get(), 1);
1683                        }
1684                        debug_assert!(is_sentinel_ptr(ns.get_parent()));
1685                        self.left_most = self.get_sentinel();
1686                        self.right_most = self.get_sentinel();
1687                        ns.set_left(core::ptr::null_mut());
1688                        ns.set_right(core::ptr::null_mut());
1689                    } else {
1690                        debug_assert!(valid_sentinel_ptr(ns.get_parent()));
1691                        debug_assert!(ns.get_right().is_null());
1692                        self.left_most = ns.get_parent();
1693                        *owner = ns.get_left();
1694                        ns.set_left(core::ptr::null_mut());
1695                    }
1696                } else if is_sentinel_ptr(ns.get_right()) {
1697                    debug_assert!(valid_sentinel_ptr(ns.get_parent()));
1698                    debug_assert!(ns.get_left().is_null());
1699                    self.right_most = ns.get_parent();
1700                    *owner = ns.get_right();
1701                    ns.set_right(core::ptr::null_mut());
1702                }
1703
1704                ns.set_parent(core::ptr::null_mut());
1705            }
1706
1707            debug_assert!(ns.is_valid() && !ns.in_container());
1708            self.observer.record_erase(target, parent);
1709
1710            self.size.decrement();
1711
1712            if !is_sentinel_ptr(parent) {
1713                if was_one_child {
1714                    self.balance_post_erase_fix_22_leaf(parent);
1715                } else {
1716                    if was_left_child {
1717                        self.balance_post_erase_fix_lr_3_child::<ForwardTraits>(parent);
1718                    } else {
1719                        self.balance_post_erase_fix_lr_3_child::<ReverseTraits>(parent);
1720                    }
1721                }
1722            }
1723
1724            Some(P::from_raw(target))
1725        }
1726    }
1727
1728    /// Replaces `old_node` with `new_node` in the tree's pointer structure.
1729    ///
1730    /// Returns the `old_node` wrapped in `P`.
1731    ///
1732    /// # Safety
1733    ///
1734    /// - `old_node` must be a valid, aligned, dereferenceable pointer to a node currently
1735    ///   contained within this tree.
1736    /// - `new_node` must be a valid node not currently contained in this or any other tree.
1737    /// - The key of `new_node` must exactly match the key of `old_node` to preserve the
1738    ///   Binary Search Tree (BST) ordering invariant.
1739    unsafe fn internal_swap(&mut self, old_node: *mut P::Target, new_node: P) -> Option<P> {
1740        // SAFETY: The caller must guarantee that `old_node` is in this tree, that `new_node`
1741        // is unlinked, and that their keys match. This method updates all parent and child
1742        // links to point to the new node, and reclaims ownership of `old_node`.
1743        unsafe {
1744            debug_assert!(!old_node.is_null());
1745            let new_raw = P::into_raw(new_node);
1746            debug_assert!(!new_raw.is_null());
1747            debug_assert!((*old_node).get_key().borrow() == (*new_raw).get_key().borrow());
1748
1749            let old_ns = Self::get_node_ref(old_node);
1750            let new_ns = Self::get_node_ref(new_raw);
1751
1752            debug_assert!(old_ns.in_container());
1753            debug_assert!(!new_ns.in_container());
1754            self.observer.record_insert_replace(old_node, new_raw);
1755
1756            if valid_sentinel_ptr(old_ns.get_left()) {
1757                Self::get_node_ref(old_ns.get_left()).set_parent(new_raw);
1758            } else {
1759                if is_sentinel_ptr(old_ns.get_left()) {
1760                    debug_assert_eq!(self.left_most, old_node);
1761                    self.left_most = new_raw;
1762                }
1763            }
1764            new_ns.set_left(old_ns.get_left());
1765            old_ns.set_left(core::ptr::null_mut());
1766
1767            if valid_sentinel_ptr(old_ns.get_right()) {
1768                Self::get_node_ref(old_ns.get_right()).set_parent(new_raw);
1769            } else {
1770                if is_sentinel_ptr(old_ns.get_right()) {
1771                    debug_assert_eq!(self.right_most, old_node);
1772                    self.right_most = new_raw;
1773                }
1774            }
1775            new_ns.set_right(old_ns.get_right());
1776            old_ns.set_right(core::ptr::null_mut());
1777
1778            *new_ns.rank.get() = *old_ns.rank.get();
1779
1780            *self.get_link_ptr_to_node(old_node) = new_raw;
1781            new_ns.set_parent(old_ns.get_parent());
1782            old_ns.set_parent(core::ptr::null_mut());
1783
1784            Some(P::from_raw(old_node))
1785        }
1786    }
1787
1788    /// Advances the node pointer `node` in-place to the next node in-order
1789    /// (according to the direction specified by `LR`).
1790    ///
1791    /// # Safety
1792    ///
1793    /// - `node` must be a valid, aligned, dereferenceable pointer to a raw pointer `*node`.
1794    /// - `*node` must point to a valid node currently contained within this tree.
1795    unsafe fn advance<LR: LrTraits>(node: &mut *mut P::Target) {
1796        // SAFETY: The caller must ensure that `*node` is a valid pointer to a node in this tree.
1797        // Traveling through parent/child links is safe as long as the tree structure is valid
1798        // and the node belongs to the tree.
1799        unsafe {
1800            debug_assert!(valid_sentinel_ptr(*node));
1801
1802            let mut ns = Self::get_node_ref(*node);
1803            let rl_child = LR::rl_child(ns);
1804            if !rl_child.is_null() {
1805                *node = rl_child;
1806
1807                if is_sentinel_ptr(*node) {
1808                    return;
1809                }
1810
1811                let mut lr_child = LR::lr_child(Self::get_node_ref(*node));
1812                while !lr_child.is_null() {
1813                    debug_assert!(!is_sentinel_ptr(lr_child));
1814                    *node = lr_child;
1815                    lr_child = LR::lr_child(Self::get_node_ref(*node));
1816                }
1817                return;
1818            }
1819
1820            let mut done;
1821            ns = Self::get_node_ref(*node);
1822            loop {
1823                debug_assert!(valid_sentinel_ptr(ns.get_parent()));
1824
1825                let parent_ns = Self::get_node_ref(ns.get_parent());
1826                done = LR::lr_child(parent_ns) == *node;
1827
1828                debug_assert!(done || LR::rl_child(parent_ns) == *node);
1829
1830                *node = ns.get_parent();
1831                ns = parent_ns;
1832
1833                if done {
1834                    break;
1835                }
1836            }
1837        }
1838    }
1839
1840    /// Advances `node` in-place to its in-order successor in the tree (setting `*node` to null
1841    /// once the end of the tree is reached), or sets `*node` to null if `*node` is already null
1842    /// or a sentinel pointer.
1843    ///
1844    /// # Safety
1845    ///
1846    /// - `node` must be a valid, aligned, dereferenceable mutable reference to a raw pointer.
1847    /// - `*node` must either be null/sentinel or point to a valid node currently contained within
1848    ///   a `WavlTree` whose structure is not being concurrently modified.
1849    pub unsafe fn successor_raw(node: &mut *mut P::Target) {
1850        if valid_sentinel_ptr(*node) {
1851            // SAFETY: `*node` is verified to be non-null and non-sentinel, and the caller
1852            // guarantees it points to a valid node in an unmodified WavlTree.
1853            unsafe {
1854                Self::advance::<ForwardTraits>(node);
1855            }
1856            if is_sentinel_ptr(*node) {
1857                *node = core::ptr::null_mut();
1858            }
1859        } else {
1860            *node = core::ptr::null_mut();
1861        }
1862    }
1863
1864    /// Inserts an element into the tree.
1865    ///
1866    /// For raw pointers, use [`insert_raw`] instead.
1867    pub fn insert(&mut self, ptr: P)
1868    where
1869        P: ManagedPtr,
1870    {
1871        // SAFETY: `P` is a `ManagedPtr`, which guarantees that the pointer is valid and that the
1872        // object will outlive its reference from this tree.
1873        unsafe { self.insert_raw(ptr) }
1874    }
1875
1876    /// Inserts an element into the tree.
1877    ///
1878    /// # Safety
1879    ///
1880    /// The caller must ensure that `ptr` is a valid pointer to a `T` and that the object outlives
1881    /// the reference from the tree.
1882    pub unsafe fn insert_raw(&mut self, ptr: P) {
1883        let mut collision = core::ptr::null_mut();
1884        // SAFETY: The caller guarantees `ptr` is valid and outlives the tree registration.
1885        let _ = unsafe { self.internal_insert(ptr, &mut collision) };
1886    }
1887
1888    /// Inserts the object pointed to by `ptr` if it is not already in the tree,
1889    /// or finds the object that `ptr` collided with instead.
1890    ///
1891    /// For raw pointers, use [`insert_or_find_raw`] instead.
1892    ///
1893    /// # Returns
1894    ///
1895    /// * `Ok(())` if there was no collision and the item was successfully inserted.
1896    ///   In this case, the tree takes ownership of `ptr`.
1897    /// * `Err((ptr, cursor))` if there was a collision. In this case, the
1898    ///   passed pointer `ptr` is returned back to the caller (not consumed), along with
1899    ///   a `CursorMut` positioned at the colliding node already in the tree.
1900    pub fn insert_or_find<'a>(&'a mut self, ptr: P) -> InsertOrFindResult<'a, K, P, Tag, S, O>
1901    where
1902        P: ManagedPtr,
1903    {
1904        // SAFETY: `P` is a `ManagedPtr`, which guarantees that the pointer is valid and that the
1905        // object will outlive its reference from this tree.
1906        unsafe { self.insert_or_find_raw(ptr) }
1907    }
1908
1909    /// Inserts the object pointed to by `ptr` if it is not already in the tree,
1910    /// or finds the object that `ptr` collided with instead.
1911    ///
1912    /// # Safety
1913    ///
1914    /// The caller must ensure that `ptr` is a valid pointer to a `T` and that the object outlives
1915    /// the reference from the tree.
1916    pub unsafe fn insert_or_find_raw<'a>(
1917        &'a mut self,
1918        ptr: P,
1919    ) -> InsertOrFindResult<'a, K, P, Tag, S, O> {
1920        let mut collision = core::ptr::null_mut();
1921        // SAFETY: The caller guarantees `ptr` is valid and outlives the tree registration.
1922        // If a collision occurs, `collision` is guaranteed to be a valid pointer to the colliding
1923        // node in this tree, which allows us to safely construct a `CursorMut` pointing to it.
1924        unsafe {
1925            match self.internal_insert(ptr, &mut collision) {
1926                Ok(()) => Ok(()),
1927                Err(ptr) => Err((ptr, CursorMut { tree: self, current: collision })),
1928            }
1929        }
1930    }
1931
1932    /// Finds the element in the tree with the same key as `*ptr` and replaces
1933    /// it with `ptr`, returning the element which was replaced.
1934    ///
1935    /// If no element in the tree shares a key with `*ptr`, simply adds `ptr` to
1936    /// the tree and returns `None`.
1937    ///
1938    /// In both cases, the input pointer `ptr` is consumed.
1939    ///
1940    /// For raw pointers, use [`insert_or_replace_raw`] instead.
1941    ///
1942    /// # Returns
1943    ///
1944    /// `Some(replaced)` containing the previous element if a collision occurred,
1945    /// or `None` if the element was newly inserted.
1946    pub fn insert_or_replace(&mut self, ptr: P) -> Option<P>
1947    where
1948        P: ManagedPtr,
1949    {
1950        // SAFETY: `P` is a `ManagedPtr`, which guarantees that the pointer is valid and that the
1951        // object will outlive its reference from this tree.
1952        unsafe { self.insert_or_replace_raw(ptr) }
1953    }
1954
1955    /// Finds the element in the tree with the same key as `*ptr` and replaces
1956    /// it with `ptr`, returning the element which was replaced.
1957    ///
1958    /// If no element in the tree shares a key with `*ptr`, simply adds `ptr` to
1959    /// the tree and returns `None`.
1960    ///
1961    /// # Safety
1962    ///
1963    /// The caller must ensure that `ptr` is a valid pointer to a `T` and that the object outlives
1964    /// the reference from the tree.
1965    pub unsafe fn insert_or_replace_raw(&mut self, ptr: P) -> Option<P> {
1966        let mut collision = core::ptr::null_mut();
1967        // SAFETY: The caller guarantees `ptr` is valid and outlives the tree registration.
1968        // If a collision occurs, `collision` points to a valid node in the tree sharing the same key,
1969        // making it safe to swap `collision` with `ptr` via `internal_swap`.
1970        unsafe {
1971            match self.internal_insert(ptr, &mut collision) {
1972                Ok(()) => None,
1973                Err(ptr) => self.internal_swap(collision, ptr),
1974            }
1975        }
1976    }
1977
1978    /// Removes and returns the first (smallest) element of the tree, or `None` if it is empty.
1979    pub fn pop_front(&mut self) -> Option<P> {
1980        if self.is_empty() {
1981            None
1982        } else {
1983            // SAFETY: If `self.is_empty()` is false, `self.left_most` is guaranteed to be a valid
1984            // pointer to a node currently contained in this tree instance.
1985            unsafe { self.internal_erase(self.left_most) }
1986        }
1987    }
1988
1989    /// Removes and returns the last (largest) element of the tree, or `None` if it is empty.
1990    pub fn pop_back(&mut self) -> Option<P> {
1991        if self.is_empty() {
1992            None
1993        } else {
1994            // SAFETY: If `self.is_empty()` is false, `self.right_most` is guaranteed to be a valid
1995            // pointer to a node currently contained in this tree instance.
1996            unsafe { self.internal_erase(self.right_most) }
1997        }
1998    }
1999
2000    /// Removes all elements from the tree.
2001    pub fn clear(&mut self) {
2002        while !self.is_empty() {
2003            self.pop_front();
2004        }
2005    }
2006
2007    /// Swaps the contents of this tree with another tree.
2008    ///
2009    /// This runs in O(1) time.
2010    pub fn swap(&mut self, other: &mut Self) {
2011        // Swap all fields except _pin and _phantom.
2012        core::mem::swap(&mut self.root, &mut other.root);
2013        core::mem::swap(&mut self.left_most, &mut other.left_most);
2014        core::mem::swap(&mut self.right_most, &mut other.right_most);
2015        core::mem::swap(&mut self.size, &mut other.size);
2016        core::mem::swap(&mut self.observer, &mut other.observer);
2017
2018        // Now repair the sentinel pointers which are self-referential.
2019        self.fix_sentinels_after_swap(other);
2020    }
2021
2022    fn fix_sentinels_after_swap(&mut self, other: &mut Self) {
2023        let self_sentinel = self.get_sentinel();
2024        let other_sentinel = other.get_sentinel();
2025
2026        // For `self` (which currently contains `other`'s old nodes):
2027        // The old sentinel in these nodes is `other_sentinel`. We update them to `self_sentinel`.
2028        if self.root.is_null() {
2029            self.left_most = self_sentinel;
2030            self.right_most = self_sentinel;
2031        } else {
2032            // SAFETY: Sentinels are verified to be valid and correspond to the correct node locations.
2033            unsafe {
2034                let root_ns = Self::get_node_ref(self.root);
2035                debug_assert_eq!(root_ns.get_parent(), other_sentinel);
2036                root_ns.set_parent(self_sentinel);
2037
2038                let left_ns = Self::get_node_ref(self.left_most);
2039                debug_assert_eq!(left_ns.get_left(), other_sentinel);
2040                left_ns.set_left(self_sentinel);
2041
2042                let right_ns = Self::get_node_ref(self.right_most);
2043                debug_assert_eq!(right_ns.get_right(), other_sentinel);
2044                right_ns.set_right(self_sentinel);
2045            }
2046        }
2047
2048        // For `other` (which currently contains `self`'s old nodes):
2049        // The old sentinel in these nodes is `self_sentinel`. We update them to `other_sentinel`.
2050        if other.root.is_null() {
2051            other.left_most = other_sentinel;
2052            other.right_most = other_sentinel;
2053        } else {
2054            // SAFETY: Sentinels are verified to be valid and correspond to the correct node locations.
2055            unsafe {
2056                let root_ns = Self::get_node_ref(other.root);
2057                debug_assert_eq!(root_ns.get_parent(), self_sentinel);
2058                root_ns.set_parent(other_sentinel);
2059
2060                let left_ns = Self::get_node_ref(other.left_most);
2061                debug_assert_eq!(left_ns.get_left(), self_sentinel);
2062                left_ns.set_left(other_sentinel);
2063
2064                let right_ns = Self::get_node_ref(other.right_most);
2065                debug_assert_eq!(right_ns.get_right(), self_sentinel);
2066                right_ns.set_right(other_sentinel);
2067            }
2068        }
2069    }
2070
2071    /// Traverses the tree to find the node with the given key.
2072    ///
2073    /// Returns a raw pointer to the matching node, or a sentinel pointer if not found.
2074    ///
2075    /// # Safety
2076    ///
2077    /// The returned raw pointer is only valid as long as the tree structure is not modified
2078    /// and no elements are deleted.
2079    unsafe fn find_raw(&self, key: &K) -> *mut P::Target {
2080        // SAFETY: Accessing node keys and traversing child pointers is safe since we only
2081        // traverse nodes contained inside this tree and ensure they are valid via `valid_sentinel_ptr`.
2082        unsafe {
2083            let mut node = self.root;
2084            while valid_sentinel_ptr(node) {
2085                let node_key = (*node).get_key();
2086                let b = node_key.borrow();
2087                if key == b {
2088                    return node;
2089                }
2090                let ns = Self::get_node_ref(node);
2091                node = if key < b { ns.get_left() } else { ns.get_right() };
2092            }
2093            self.get_sentinel()
2094        }
2095    }
2096
2097    /// Traverses the tree to find either the lower bound or upper bound node pointer.
2098    ///
2099    /// # Safety
2100    ///
2101    /// The returned raw pointer is only valid as long as the tree structure is not modified
2102    /// and no elements are deleted.
2103    unsafe fn bound_raw(&self, key: &K, strictly_greater: bool) -> *mut P::Target {
2104        // SAFETY: Accessing node keys and traversing child pointers is safe since we only
2105        // traverse nodes contained inside this tree and ensure they are valid via `valid_sentinel_ptr`.
2106        unsafe {
2107            let mut node = self.root;
2108            let mut found = self.get_sentinel();
2109
2110            while valid_sentinel_ptr(node) {
2111                let node_key = (*node).get_key();
2112                let b = node_key.borrow();
2113                let is_eligible = if strictly_greater { b > key } else { b >= key };
2114                if is_eligible {
2115                    found = node;
2116                    node = Self::get_node_ref(node).get_left();
2117                } else {
2118                    node = Self::get_node_ref(node).get_right();
2119                }
2120            }
2121            found
2122        }
2123    }
2124
2125    /// Finds an element in the tree by key.
2126    pub fn find(&self, key: &K) -> Option<&P::Target> {
2127        // SAFETY: find_raw returns either a sentinel pointer or a valid node in the tree.
2128        // If it is valid, returning a reference is safe for the lifetime of the borrow of `self`.
2129        unsafe {
2130            let node = self.find_raw(key);
2131            if valid_sentinel_ptr(node) { Some(&*node) } else { None }
2132        }
2133    }
2134
2135    /// Finds an element in the tree by key and returns a cursor positioned at it.
2136    ///
2137    /// If the key is not found, the returned cursor is positioned at the sentinel
2138    /// (i.e. `cursor.get()` will return `None`).
2139    pub fn find_cursor(&mut self, key: &K) -> CursorMut<'_, K, P, Tag, S, O> {
2140        // SAFETY: find_raw returns a valid node pointer or sentinel pointer belonging to this tree.
2141        let node = unsafe { self.find_raw(key) };
2142        CursorMut { tree: self, current: node }
2143    }
2144
2145    /// Returns a cursor positioned at the lower bound of the key (the first element
2146    /// in the tree whose key is greater than or equal to `key`).
2147    ///
2148    /// If no such element exists (e.g. all elements in the tree are smaller than `key`),
2149    /// the returned cursor is positioned at the sentinel.
2150    pub fn lower_bound(&mut self, key: &K) -> CursorMut<'_, K, P, Tag, S, O> {
2151        // SAFETY: bound_raw returns a valid node pointer or sentinel pointer in the tree.
2152        let node = unsafe { self.bound_raw(key, false) };
2153        CursorMut { tree: self, current: node }
2154    }
2155
2156    /// Returns a cursor positioned at the upper bound of the key (the first element
2157    /// in the tree whose key is strictly greater than `key`).
2158    ///
2159    /// If no such element exists (e.g. all elements in the tree are smaller than or
2160    /// equal to `key`), the returned cursor is positioned at the sentinel.
2161    pub fn upper_bound(&mut self, key: &K) -> CursorMut<'_, K, P, Tag, S, O> {
2162        // SAFETY: bound_raw returns a valid node pointer or sentinel pointer in the tree.
2163        let node = unsafe { self.bound_raw(key, true) };
2164        CursorMut { tree: self, current: node }
2165    }
2166
2167    /// Erases an element by key.
2168    pub fn erase(&mut self, key: &K) -> Option<P> {
2169        let mut cursor = self.find_cursor(key);
2170        cursor.erase()
2171    }
2172
2173    /// Erases an element by raw pointer.
2174    ///
2175    /// # Safety
2176    ///
2177    /// The caller must ensure that `obj` is a valid pointer to an object that is currently
2178    /// contained within this tree instance.
2179    pub unsafe fn erase_raw(&mut self, obj: *mut P::Target) -> Option<P> {
2180        // SAFETY: The caller guarantees that `obj` is currently contained in this WavlTree.
2181        // `internal_erase` is safe to execute on a contained pointer.
2182        unsafe {
2183            let node = (*obj).get_node();
2184            if !node.in_container() {
2185                return None;
2186            }
2187            self.internal_erase(obj)
2188        }
2189    }
2190
2191    /// Returns a cursor positioned at the front (smallest element) of the tree.
2192    pub fn cursor_mut(&mut self) -> CursorMut<'_, K, P, Tag, S, O> {
2193        let left_most = self.left_most;
2194        CursorMut { tree: self, current: left_most }
2195    }
2196
2197    /// Returns a read-only cursor positioned at the given element.
2198    ///
2199    /// # Safety
2200    ///
2201    /// The caller must ensure that `obj` is a member of this tree.
2202    /// It is undefined behavior to use the returned cursor if `obj` is not in the tree,
2203    /// or if it is in a different tree.
2204    pub unsafe fn cursor_at(&self, obj: &P::Target) -> Cursor<'_, K, P, Tag, S, O> {
2205        assert!(obj.get_node().in_container(), "Object must be in a container");
2206        Cursor { tree: self, current: obj as *const P::Target as *mut P::Target }
2207    }
2208
2209    /// Returns a mutable cursor positioned at the given element.
2210    ///
2211    /// # Safety
2212    ///
2213    /// The caller must ensure that `obj` is a member of this tree.
2214    /// It is undefined behavior to use the returned cursor if `obj` is not in the tree,
2215    /// or if it is in a different tree.
2216    pub unsafe fn cursor_mut_at(&mut self, obj: &P::Target) -> CursorMut<'_, K, P, Tag, S, O> {
2217        assert!(obj.get_node().in_container(), "Object must be in a container");
2218        CursorMut { tree: self, current: obj as *const P::Target as *mut P::Target }
2219    }
2220
2221    /// Returns an iterator over the elements of the tree.
2222    pub fn iter(&self) -> Iterator<'_, K, P, Tag, S, O> {
2223        Iterator::new(self)
2224    }
2225
2226    /// Returns a unidirectional forward iterator over the elements of the tree.
2227    pub fn forward_iter(&self) -> ForwardIterator<'_, K, P, Tag, S, O> {
2228        ForwardIterator::new(self.left_most)
2229    }
2230
2231    /// Returns a unidirectional reverse iterator over the elements of the tree.
2232    pub fn reverse_iter(&self) -> ReverseIterator<'_, K, P, Tag, S, O> {
2233        ReverseIterator::new(self.right_most)
2234    }
2235
2236    /// Returns a read-only cursor positioned at the root of the tree.
2237    pub fn root_cursor(&self) -> Cursor<'_, K, P, Tag, S, O> {
2238        Cursor { tree: self, current: self.root }
2239    }
2240
2241    /// Returns a read-only cursor positioned at the first (smallest) element.
2242    pub fn front_cursor(&self) -> Cursor<'_, K, P, Tag, S, O> {
2243        Cursor { tree: self, current: self.left_most }
2244    }
2245
2246    /// Returns a read-only cursor positioned at the last (largest) element.
2247    pub fn back_cursor(&self) -> Cursor<'_, K, P, Tag, S, O> {
2248        Cursor { tree: self, current: self.right_most }
2249    }
2250
2251    /// Returns the number of elements in the tree.
2252    pub fn len(&self) -> usize {
2253        self.size.get()
2254    }
2255}
2256
2257#[pinned_drop]
2258impl<K, P, Tag, S, O> PinnedDrop for WavlTree<K, P, Tag, S, O>
2259where
2260    P: PtrTraits,
2261    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2262    K: Ord,
2263    S: SizeTracker,
2264    O: WavlTreeObserver<Target = P::Target>,
2265{
2266    fn drop(self: Pin<&mut Self>) {
2267        if P::IS_MANAGED {
2268            let me = unsafe { self.get_unchecked_mut() };
2269            me.clear();
2270        } else {
2271            debug_assert!(self.is_empty(), "Tree must be empty on destruction");
2272            if S::IS_TRACKING {
2273                debug_assert_eq!(self.size.get(), 0, "Size must be zero on destruction");
2274            }
2275        }
2276    }
2277}
2278
2279/// A read-only cursor positioned in a `WavlTree`.
2280pub struct Cursor<
2281    'a,
2282    K,
2283    P,
2284    Tag = DefaultObjectTag,
2285    S = NonTrackingSize,
2286    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2287> where
2288    P: PtrTraits,
2289    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2290    K: Ord,
2291    S: SizeTracker,
2292    O: WavlTreeObserver<Target = P::Target>,
2293{
2294    tree: &'a WavlTree<K, P, Tag, S, O>,
2295    current: *mut P::Target,
2296}
2297
2298impl<'a, K, P, Tag, S, O> Clone for Cursor<'a, K, P, Tag, S, O>
2299where
2300    P: PtrTraits,
2301    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2302    K: Ord,
2303    S: SizeTracker,
2304    O: WavlTreeObserver<Target = P::Target>,
2305{
2306    fn clone(&self) -> Self {
2307        *self
2308    }
2309}
2310
2311impl<'a, K, P, Tag, S, O> Copy for Cursor<'a, K, P, Tag, S, O>
2312where
2313    P: PtrTraits,
2314    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2315    K: Ord,
2316    S: SizeTracker,
2317    O: WavlTreeObserver<Target = P::Target>,
2318{
2319}
2320
2321impl<'a, K, P, Tag, S, O> PartialEq for Cursor<'a, K, P, Tag, S, O>
2322where
2323    P: PtrTraits,
2324    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2325    K: Ord,
2326    S: SizeTracker,
2327    O: WavlTreeObserver<Target = P::Target>,
2328{
2329    fn eq(&self, other: &Self) -> bool {
2330        self.current == other.current
2331    }
2332}
2333
2334impl<'a, K, P, Tag, S, O> core::fmt::Debug for Cursor<'a, K, P, Tag, S, O>
2335where
2336    P: PtrTraits,
2337    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2338    K: Ord,
2339    S: SizeTracker,
2340    O: WavlTreeObserver<Target = P::Target>,
2341{
2342    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2343        f.debug_struct("Cursor").field("current", &self.current).finish()
2344    }
2345}
2346
2347impl<'a, K, P, Tag, S, O> Cursor<'a, K, P, Tag, S, O>
2348where
2349    P: PtrTraits,
2350    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2351    K: Ord,
2352    S: SizeTracker,
2353    O: WavlTreeObserver<Target = P::Target>,
2354{
2355    /// Returns a reference to the current element, or `None` if the cursor is not at a valid
2356    /// element (null or the sentinel).
2357    pub fn get(&self) -> Option<&'a P::Target> {
2358        if !valid_sentinel_ptr(self.current) {
2359            None
2360        } else {
2361            // SAFETY: `self.current` is checked to be non-null and non-sentinel, so it points to
2362            // a node in the tree. The lifetime `'a` is tied to the `WavlTree` borrow.
2363            unsafe { Some(&*self.current) }
2364        }
2365    }
2366
2367    /// Returns true if the cursor is positioned at a valid element (not the sentinel).
2368    pub fn is_valid(&self) -> bool {
2369        valid_sentinel_ptr(self.current)
2370    }
2371
2372    /// Returns a cursor positioned at the left child of the current element.
2373    /// If the current element is the sentinel, returns a cursor at the sentinel.
2374    pub fn left(&self) -> Self {
2375        if !self.is_valid() {
2376            *self
2377        } else {
2378            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2379            // non-null node in the tree because `current` is never null). Accessing the tree node state is safe.
2380            let ns = unsafe { WavlTree::<K, P, Tag, S, O>::get_node_ref(self.current) };
2381            Self { tree: self.tree, current: ns.get_left() }
2382        }
2383    }
2384
2385    /// Returns a cursor positioned at the right child of the current element.
2386    pub fn right(&self) -> Self {
2387        if !self.is_valid() {
2388            *self
2389        } else {
2390            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2391            // non-null node in the tree because `current` is never null). Accessing the tree node state is safe.
2392            let ns = unsafe { WavlTree::<K, P, Tag, S, O>::get_node_ref(self.current) };
2393            Self { tree: self.tree, current: ns.get_right() }
2394        }
2395    }
2396
2397    /// Returns a cursor positioned at the parent of the current element.
2398    pub fn parent(&self) -> Self {
2399        if !self.is_valid() {
2400            *self
2401        } else {
2402            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2403            // non-null node in the tree because `current` is never null). Accessing the tree node state is safe.
2404            let ns = unsafe { WavlTree::<K, P, Tag, S, O>::get_node_ref(self.current) };
2405            let parent = ns.get_parent();
2406            Self { tree: self.tree, current: parent }
2407        }
2408    }
2409
2410    /// Returns the raw pointer to the current element.
2411    /// This may be a sentinel pointer if the cursor is at the sentinel.
2412    pub fn as_raw_ptr(&self) -> *mut P::Target {
2413        self.current
2414    }
2415}
2416
2417pub type InsertOrFindResult<'a, K, P, Tag, S, O> = Result<(), (P, CursorMut<'a, K, P, Tag, S, O>)>;
2418
2419/// A cursor over elements in a `WavlTree`.
2420pub struct CursorMut<
2421    'a,
2422    K,
2423    P,
2424    Tag = DefaultObjectTag,
2425    S = NonTrackingSize,
2426    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2427> where
2428    P: PtrTraits,
2429    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2430    K: Ord,
2431    S: SizeTracker,
2432    O: WavlTreeObserver<Target = P::Target>,
2433{
2434    tree: &'a mut WavlTree<K, P, Tag, S, O>,
2435    current: *mut P::Target,
2436}
2437
2438impl<'a, K, P, Tag, S, O> CursorMut<'a, K, P, Tag, S, O>
2439where
2440    P: PtrTraits,
2441    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2442    K: Ord,
2443    S: SizeTracker,
2444    O: WavlTreeObserver<Target = P::Target>,
2445{
2446    /// Returns a reference to the current element, or `None` if the cursor is not at a valid
2447    /// element (null or the sentinel).
2448    pub fn get(&self) -> Option<&P::Target> {
2449        if !valid_sentinel_ptr(self.current) {
2450            None
2451        } else {
2452            // SAFETY: `self.current` is checked to be non-null and non-sentinel, so it points to
2453            // a node in the tree. Since `CursorMut` mutably borrows the tree, the node is
2454            // guaranteed to be valid and dereferenceable for the lifetime of the reference.
2455            unsafe { Some(&*self.current) }
2456        }
2457    }
2458
2459    /// Moves the cursor to the next (larger) element.
2460    pub fn move_next(&mut self) {
2461        if valid_sentinel_ptr(self.current) {
2462            // SAFETY: `self.current` is verified to be a valid node in the tree. Advancing through
2463            // tree pointers is safe.
2464            unsafe {
2465                WavlTree::<K, P, Tag, S, O>::advance::<ForwardTraits>(&mut self.current);
2466            }
2467        }
2468    }
2469
2470    /// Moves the cursor to the previous (smaller) element.
2471    pub fn move_prev(&mut self) {
2472        if valid_sentinel_ptr(self.current) {
2473            // SAFETY: `self.current` is verified to be a valid node in the tree. Advancing through
2474            // tree pointers is safe.
2475            unsafe {
2476                WavlTree::<K, P, Tag, S, O>::advance::<ReverseTraits>(&mut self.current);
2477            }
2478        } else if is_sentinel_ptr(self.current) {
2479            self.current = self.tree.right_most;
2480        }
2481    }
2482
2483    /// Erases the current element and moves the cursor to the next element.
2484    pub fn erase(&mut self) -> Option<P> {
2485        if !valid_sentinel_ptr(self.current) {
2486            return None;
2487        }
2488
2489        let to_erase = self.current;
2490        // SAFETY: `to_erase` is verified to be a valid, non-sentinel node in the tree.
2491        // `advance` moves the cursor to a safe position before `internal_erase` physically removes
2492        // `to_erase` from the tree.
2493        unsafe {
2494            WavlTree::<K, P, Tag, S, O>::advance::<ForwardTraits>(&mut self.current);
2495            self.tree.internal_erase(to_erase)
2496        }
2497    }
2498}
2499
2500/// A unidirectional forward iterator over the elements of a `WavlTree`.
2501pub struct ForwardIterator<
2502    'a,
2503    K,
2504    P,
2505    Tag = DefaultObjectTag,
2506    S = NonTrackingSize,
2507    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2508> where
2509    P: PtrTraits,
2510    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2511    K: Ord,
2512    S: SizeTracker,
2513    O: WavlTreeObserver<Target = P::Target>,
2514{
2515    current: *mut P::Target,
2516    _phantom: core::marker::PhantomData<&'a WavlTree<K, P, Tag, S, O>>,
2517}
2518
2519impl<'a, K, P, Tag, S, O> ForwardIterator<'a, K, P, Tag, S, O>
2520where
2521    P: PtrTraits,
2522    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2523    K: Ord,
2524    S: SizeTracker,
2525    O: WavlTreeObserver<Target = P::Target>,
2526{
2527    fn new(current: *mut P::Target) -> Self {
2528        Self { current, _phantom: core::marker::PhantomData }
2529    }
2530
2531    /// Creates an iterator starting from a specific element.
2532    ///
2533    /// # Panics
2534    ///
2535    /// Panics if the object is not in a container.
2536    pub fn from_element(obj: &'a P::Target) -> Self {
2537        assert!(obj.get_node().in_container(), "Object must be in a container");
2538        Self { current: obj as *const _ as *mut _, _phantom: core::marker::PhantomData }
2539    }
2540
2541    fn get_current(&self) -> Option<&'a P::Target> {
2542        if is_sentinel_ptr(self.current) {
2543            None
2544        } else {
2545            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2546            // non-null node in the tree because `current` is never null). Since the iterator
2547            // holds a lifetime borrow of the `WavlTree`, and the tree remains unmodified,
2548            // the node is guaranteed to be valid and dereferenceable for `'a`.
2549            unsafe { Some(&*self.current) }
2550        }
2551    }
2552}
2553
2554impl<'a, K, P, Tag, S, O> Clone for ForwardIterator<'a, K, P, Tag, S, O>
2555where
2556    P: PtrTraits,
2557    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2558    K: Ord,
2559    S: SizeTracker,
2560    O: WavlTreeObserver<Target = P::Target>,
2561{
2562    fn clone(&self) -> Self {
2563        Self { current: self.current, _phantom: core::marker::PhantomData }
2564    }
2565}
2566
2567impl<'a, K, P, Tag, S, O> core::iter::Iterator for ForwardIterator<'a, K, P, Tag, S, O>
2568where
2569    P: PtrTraits,
2570    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2571    K: Ord,
2572    S: SizeTracker,
2573    O: WavlTreeObserver<Target = P::Target>,
2574{
2575    type Item = &'a P::Target;
2576
2577    fn next(&mut self) -> Option<Self::Item> {
2578        let current = self.get_current()?;
2579        // SAFETY: `self.current` is validated as non-sentinel by `get_current`.
2580        // Moving through tree pointers is safe.
2581        unsafe {
2582            WavlTree::<K, P, Tag, S, O>::advance::<ForwardTraits>(&mut self.current);
2583        }
2584        Some(current)
2585    }
2586}
2587
2588/// A unidirectional reverse iterator over the elements of a `WavlTree`.
2589pub struct ReverseIterator<
2590    'a,
2591    K,
2592    P,
2593    Tag = DefaultObjectTag,
2594    S = NonTrackingSize,
2595    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2596> where
2597    P: PtrTraits,
2598    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2599    K: Ord,
2600    S: SizeTracker,
2601    O: WavlTreeObserver<Target = P::Target>,
2602{
2603    current: *mut P::Target,
2604    _phantom: core::marker::PhantomData<&'a WavlTree<K, P, Tag, S, O>>,
2605}
2606
2607impl<'a, K, P, Tag, S, O> ReverseIterator<'a, K, P, Tag, S, O>
2608where
2609    P: PtrTraits,
2610    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2611    K: Ord,
2612    S: SizeTracker,
2613    O: WavlTreeObserver<Target = P::Target>,
2614{
2615    fn new(current: *mut P::Target) -> Self {
2616        Self { current, _phantom: core::marker::PhantomData }
2617    }
2618
2619    /// Creates an iterator starting from a specific element.
2620    ///
2621    /// # Panics
2622    ///
2623    /// Panics if the object is not in a container.
2624    pub fn from_element(obj: &'a P::Target) -> Self {
2625        assert!(obj.get_node().in_container(), "Object must be in a container");
2626        Self { current: obj as *const _ as *mut _, _phantom: core::marker::PhantomData }
2627    }
2628
2629    fn get_current(&self) -> Option<&'a P::Target> {
2630        if is_sentinel_ptr(self.current) {
2631            None
2632        } else {
2633            // SAFETY: `self.current` is checked to be non-sentinel (which implies it is a valid,
2634            // non-null node in the tree because `current` is never null). Since the iterator
2635            // holds a lifetime borrow of the `WavlTree`, and the tree remains unmodified,
2636            // the node is guaranteed to be valid and dereferenceable for `'a`.
2637            unsafe { Some(&*self.current) }
2638        }
2639    }
2640}
2641
2642impl<'a, K, P, Tag, S, O> Clone for ReverseIterator<'a, K, P, Tag, S, O>
2643where
2644    P: PtrTraits,
2645    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2646    K: Ord,
2647    S: SizeTracker,
2648    O: WavlTreeObserver<Target = P::Target>,
2649{
2650    fn clone(&self) -> Self {
2651        Self { current: self.current, _phantom: core::marker::PhantomData }
2652    }
2653}
2654
2655impl<'a, K, P, Tag, S, O> core::iter::Iterator for ReverseIterator<'a, K, P, Tag, S, O>
2656where
2657    P: PtrTraits,
2658    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2659    K: Ord,
2660    S: SizeTracker,
2661    O: WavlTreeObserver<Target = P::Target>,
2662{
2663    type Item = &'a P::Target;
2664
2665    fn next(&mut self) -> Option<Self::Item> {
2666        let current = self.get_current()?;
2667        // SAFETY: `self.current` is validated as non-sentinel by `get_current`.
2668        // Moving through tree pointers is safe.
2669        unsafe {
2670            WavlTree::<K, P, Tag, S, O>::advance::<ReverseTraits>(&mut self.current);
2671        }
2672        Some(current)
2673    }
2674}
2675
2676/// An iterator over the elements of a `WavlTree`.
2677pub struct Iterator<
2678    'a,
2679    K,
2680    P,
2681    Tag = DefaultObjectTag,
2682    S = NonTrackingSize,
2683    O = DefaultWavlTreeObserver<<P as PtrTraits>::Target>,
2684> where
2685    P: PtrTraits,
2686    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2687    K: Ord,
2688    S: SizeTracker,
2689    O: WavlTreeObserver<Target = P::Target>,
2690{
2691    front: ForwardIterator<'a, K, P, Tag, S, O>,
2692    back: ReverseIterator<'a, K, P, Tag, S, O>,
2693}
2694
2695impl<'a, K, P, Tag, S, O> Iterator<'a, K, P, Tag, S, O>
2696where
2697    P: PtrTraits,
2698    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2699    K: Ord,
2700    S: SizeTracker,
2701    O: WavlTreeObserver<Target = P::Target>,
2702{
2703    fn new(tree: &'a WavlTree<K, P, Tag, S, O>) -> Self {
2704        if tree.is_empty() {
2705            Self {
2706                front: ForwardIterator::new(make_sentinel_null()),
2707                back: ReverseIterator::new(make_sentinel_null()),
2708            }
2709        } else {
2710            Self {
2711                front: ForwardIterator::new(tree.left_most),
2712                back: ReverseIterator::new(tree.right_most),
2713            }
2714        }
2715    }
2716}
2717
2718impl<'a, K, P, Tag, S, O> Clone for Iterator<'a, K, P, Tag, S, O>
2719where
2720    P: PtrTraits,
2721    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2722    K: Ord,
2723    S: SizeTracker,
2724    O: WavlTreeObserver<Target = P::Target>,
2725{
2726    fn clone(&self) -> Self {
2727        Self { front: self.front.clone(), back: self.back.clone() }
2728    }
2729}
2730
2731impl<'a, K, P, Tag, S, O> core::iter::Iterator for Iterator<'a, K, P, Tag, S, O>
2732where
2733    P: PtrTraits,
2734    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2735    K: Ord,
2736    S: SizeTracker,
2737    O: WavlTreeObserver<Target = P::Target>,
2738{
2739    type Item = &'a P::Target;
2740
2741    fn next(&mut self) -> Option<Self::Item> {
2742        let met = self.front.current == self.back.current;
2743        let item = self.front.next();
2744        if item.is_some() && met {
2745            self.front.current = make_sentinel_null();
2746            self.back.current = make_sentinel_null();
2747        }
2748        item
2749    }
2750}
2751
2752impl<'a, K, P, Tag, S, O> core::iter::DoubleEndedIterator for Iterator<'a, K, P, Tag, S, O>
2753where
2754    P: PtrTraits,
2755    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
2756    K: Ord,
2757    S: SizeTracker,
2758    O: WavlTreeObserver<Target = P::Target>,
2759{
2760    fn next_back(&mut self) -> Option<Self::Item> {
2761        let met = self.front.current == self.back.current;
2762        let item = self.back.next();
2763        if item.is_some() && met {
2764            self.front.current = make_sentinel_null();
2765            self.back.current = make_sentinel_null();
2766        }
2767        item
2768    }
2769}
2770
2771impl<K, T, Tag, S, O> WavlTree<K, *mut T, Tag, S, O>
2772where
2773    T: WavlTreeContainable<T, Tag> + WavlTreeKeyable<K>,
2774    K: Ord,
2775    S: SizeTracker,
2776    O: WavlTreeObserver<Target = T>,
2777{
2778    /// Unsafely removes all elements from the tree without modifying node memory.
2779    ///
2780    /// This method resets the tree's internal pointers, effectively emptying it, but does
2781    /// NOT modify the node state of the elements that were in the tree.
2782    ///
2783    /// # Safety
2784    ///
2785    /// Because the nodes are not modified, they will still believe they are in a container
2786    /// (i.e. `in_container()` will return `true` for them). If these elements are subsequently
2787    /// dropped, they will trigger a `debug_assert` panic (as `WavlTreeNode` asserts on drop
2788    /// that it is not in a container).
2789    ///
2790    /// The caller is responsible for manually clearing the node state of the elements, or
2791    /// ensuring they are never dropped while in this "dirty" state.
2792    ///
2793    /// Only usable with containers of unmanaged pointers. Think carefully before calling this!
2794    pub fn clear_unsafe(&mut self) {
2795        self.root = core::ptr::null_mut();
2796        self.left_most = self.get_sentinel();
2797        self.right_most = self.get_sentinel();
2798        self.size.set(0);
2799    }
2800}
2801
2802impl<K, P, Tag, S, O> core::fmt::Debug for WavlTree<K, P, Tag, S, O>
2803where
2804    P: PtrTraits,
2805    P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K> + core::fmt::Debug,
2806    K: Ord,
2807    S: SizeTracker,
2808    O: WavlTreeObserver<Target = P::Target>,
2809{
2810    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2811        f.debug_list().entries(self.iter()).finish()
2812    }
2813}
2814
2815#[cfg(test)]
2816mod tests {
2817    use super::*;
2818    use crate::intrusive_container_test_support::*;
2819    use crate::ref_counted::HasRefCount;
2820    use crate::ref_ptr::RefPtr;
2821    use crate::size_tracker::TrackingSize;
2822    use crate::unique_ptr::UniquePtr;
2823    use crate::{Recyclable, WavlTreeContainable};
2824    use core::ffi::c_void;
2825    use pin_init::stack_pin_init;
2826
2827    trait AsTargetRef {
2828        type Target;
2829        unsafe fn as_target_ref(&self) -> &Self::Target;
2830    }
2831
2832    impl<T> AsTargetRef for *mut T {
2833        type Target = T;
2834        unsafe fn as_target_ref(&self) -> &T {
2835            unsafe { &**self }
2836        }
2837    }
2838
2839    impl<T: Recyclable> AsTargetRef for UniquePtr<T> {
2840        type Target = T;
2841        unsafe fn as_target_ref(&self) -> &T {
2842            &**self
2843        }
2844    }
2845
2846    impl<T: HasRefCount + Recyclable> AsTargetRef for RefPtr<T> {
2847        type Target = T;
2848        unsafe fn as_target_ref(&self) -> &T {
2849            &**self
2850        }
2851    }
2852
2853    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
2854    struct TestObject {
2855        value: i32,
2856        #[wavl_node]
2857        node: WavlTreeNode<TestObject>,
2858    }
2859
2860    impl TestObject {
2861        fn new(value: i32) -> Self {
2862            Self { value, node: WavlTreeNode::new() }
2863        }
2864    }
2865
2866    impl WavlTreeKeyable<i32> for TestObject {
2867        type Key<'a> = i32;
2868        fn get_key(&self) -> i32 {
2869            self.value
2870        }
2871    }
2872
2873    impl TestValue for TestObject {
2874        fn new(value: i32) -> Self {
2875            Self::new(value)
2876        }
2877    }
2878
2879    ::zr::static_assert!(
2880        core::mem::size_of::<WavlTree<i32, *mut TestObject>>()
2881            == 3 * core::mem::size_of::<*mut TestObject>()
2882    );
2883    ::zr::static_assert!(
2884        core::mem::align_of::<WavlTree<i32, *mut TestObject>>()
2885            == core::mem::align_of::<*mut TestObject>()
2886    );
2887
2888    ::zr::static_assert!(
2889        core::mem::size_of::<WavlTree<i32, *mut TestObject, DefaultObjectTag, TrackingSize>>()
2890            == 4 * core::mem::size_of::<*mut TestObject>()
2891    );
2892    ::zr::static_assert!(
2893        core::mem::align_of::<WavlTree<i32, *mut TestObject, DefaultObjectTag, TrackingSize>>()
2894            == core::mem::align_of::<*mut TestObject>()
2895    );
2896
2897    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
2898    struct UniqueTestObject {
2899        value: i32,
2900        #[wavl_node]
2901        node: WavlTreeNode<UniqueTestObject>,
2902    }
2903
2904    impl UniqueTestObject {
2905        fn new(value: i32) -> Self {
2906            Self { value, node: WavlTreeNode::new() }
2907        }
2908    }
2909
2910    impl WavlTreeKeyable<i32> for UniqueTestObject {
2911        type Key<'a> = i32;
2912        fn get_key(&self) -> i32 {
2913            self.value
2914        }
2915    }
2916
2917    impl TestValue for UniqueTestObject {
2918        fn new(value: i32) -> Self {
2919            Self::new(value)
2920        }
2921    }
2922
2923    #[fbl::ref_counted]
2924    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
2925    #[repr(C)]
2926    pub struct RefTestObject {
2927        value: i32,
2928        #[wavl_node]
2929        node: WavlTreeNode<RefTestObject>,
2930    }
2931
2932    impl WavlTreeKeyable<i32> for RefTestObject {
2933        type Key<'a> = i32;
2934        fn get_key(&self) -> i32 {
2935            self.value
2936        }
2937    }
2938
2939    impl TestValue for RefTestObject {
2940        fn new_ref_counted(value: i32) -> RefPtr<Self> {
2941            crate::make_ref_counted!(RefTestObject { value: value, node: WavlTreeNode::new() })
2942                .unwrap()
2943        }
2944    }
2945
2946    macro_rules! generate_tree_tests {
2947        ($mod_name:ident, $ptr_type:ty, $factory_type:ty, $get_val:expr, $insert:expr, $insert_or_find:expr, $insert_or_replace:expr) => {
2948            mod $mod_name {
2949                use super::*;
2950
2951                #[test]
2952                fn test_basic_sorting() {
2953                    let mut factory = <$factory_type>::new();
2954                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2955                    let tree = unsafe { tree.get_unchecked_mut() };
2956                    assert!(tree.is_empty());
2957
2958                    // Insert in scrambled order
2959                    $insert(tree, factory.create(3));
2960                    $insert(tree, factory.create(1));
2961                    $insert(tree, factory.create(4));
2962                    $insert(tree, factory.create(2));
2963
2964                    assert!(!tree.is_empty());
2965
2966                    // Iteration should be sorted
2967                    let mut iter = tree.iter();
2968                    assert_eq!($get_val(iter.next().unwrap()), 1);
2969                    assert_eq!($get_val(iter.next().unwrap()), 2);
2970                    assert_eq!($get_val(iter.next().unwrap()), 3);
2971                    assert_eq!($get_val(iter.next().unwrap()), 4);
2972                    assert!(iter.next().is_none());
2973
2974                    tree.clear();
2975                    assert!(tree.is_empty());
2976                }
2977
2978                #[test]
2979                fn test_double_ended_iterator() {
2980                    let mut factory = <$factory_type>::new();
2981                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
2982                    let tree = unsafe { tree.get_unchecked_mut() };
2983                    $insert(tree, factory.create(30));
2984                    $insert(tree, factory.create(10));
2985                    $insert(tree, factory.create(20));
2986
2987                    let mut iter = tree.iter();
2988                    assert_eq!($get_val(iter.next().unwrap()), 10);
2989                    assert_eq!($get_val(iter.next_back().unwrap()), 30);
2990                    assert_eq!($get_val(iter.next().unwrap()), 20);
2991                    assert!(iter.next().is_none());
2992                    assert!(iter.next_back().is_none());
2993
2994                    tree.clear();
2995                }
2996
2997                #[test]
2998                fn test_find() {
2999                    let mut factory = <$factory_type>::new();
3000                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3001                    let tree = unsafe { tree.get_unchecked_mut() };
3002                    $insert(tree, factory.create(3));
3003                    $insert(tree, factory.create(1));
3004                    $insert(tree, factory.create(2));
3005
3006                    assert!(tree.find(&2).is_some());
3007                    assert_eq!($get_val(tree.find(&2).unwrap()), 2);
3008                    assert!(tree.find(&4).is_none());
3009
3010                    tree.clear();
3011                }
3012
3013                #[test]
3014                fn test_bounds() {
3015                    let mut factory = <$factory_type>::new();
3016                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3017                    let tree = unsafe { tree.get_unchecked_mut() };
3018                    $insert(tree, factory.create(10));
3019                    $insert(tree, factory.create(30));
3020                    $insert(tree, factory.create(20));
3021
3022                    // lower_bound(>=)
3023                    assert_eq!($get_val(tree.lower_bound(&15).get().unwrap()), 20);
3024                    assert_eq!($get_val(tree.lower_bound(&20).get().unwrap()), 20);
3025                    assert!(tree.lower_bound(&35).get().is_none());
3026
3027                    // upper_bound(>)
3028                    assert_eq!($get_val(tree.upper_bound(&15).get().unwrap()), 20);
3029                    assert_eq!($get_val(tree.upper_bound(&20).get().unwrap()), 30);
3030                    assert!(tree.upper_bound(&30).get().is_none());
3031
3032                    tree.clear();
3033                }
3034
3035                #[test]
3036                fn test_pops() {
3037                    let mut factory = <$factory_type>::new();
3038                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3039                    let tree = unsafe { tree.get_unchecked_mut() };
3040                    $insert(tree, factory.create(10));
3041                    $insert(tree, factory.create(30));
3042                    $insert(tree, factory.create(20));
3043
3044                    let popped = tree.pop_front();
3045                    assert!(popped.is_some());
3046                    let val = popped.unwrap();
3047                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 10);
3048
3049                    let popped = tree.pop_back();
3050                    assert!(popped.is_some());
3051                    let val = popped.unwrap();
3052                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 30);
3053
3054                    let popped = tree.pop_front();
3055                    assert!(popped.is_some());
3056                    let val = popped.unwrap();
3057                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 20);
3058
3059                    assert!(tree.pop_front().is_none());
3060                }
3061
3062                #[test]
3063                fn test_erase_cursor() {
3064                    let mut factory = <$factory_type>::new();
3065                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3066                    let tree = unsafe { tree.get_unchecked_mut() };
3067                    $insert(tree, factory.create(10));
3068                    $insert(tree, factory.create(30));
3069                    $insert(tree, factory.create(20));
3070
3071                    let mut cursor = tree.find_cursor(&20);
3072                    let erased = cursor.erase();
3073                    assert!(erased.is_some());
3074                    let val = erased.unwrap();
3075                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 20);
3076
3077                    // Cursor should advance to next element (30)
3078                    assert_eq!($get_val(cursor.get().unwrap()), 30);
3079
3080                    let mut iter = tree.iter();
3081                    assert_eq!($get_val(iter.next().unwrap()), 10);
3082                    assert_eq!($get_val(iter.next().unwrap()), 30);
3083                    assert!(iter.next().is_none());
3084
3085                    tree.clear();
3086                }
3087
3088                #[test]
3089                fn test_insert_or_find() {
3090                    let mut factory = <$factory_type>::new();
3091                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3092                    let tree = unsafe { tree.get_unchecked_mut() };
3093                    $insert(tree, factory.create(10));
3094
3095                    let new_item = factory.create(10); // Duplicate key
3096                    let res = $insert_or_find(tree, new_item);
3097                    assert!(res.is_err());
3098                    let (failed_ptr, collision) = res.err().unwrap();
3099                    assert_eq!($get_val(unsafe { failed_ptr.as_target_ref() }), 10);
3100                    assert_eq!($get_val(collision.get().unwrap()), 10);
3101
3102                    let ok_item = factory.create(20);
3103                    assert!($insert_or_find(tree, ok_item).is_ok());
3104
3105                    tree.clear();
3106                }
3107
3108                #[test]
3109                fn test_insert_or_replace() {
3110                    let mut factory = <$factory_type>::new();
3111                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3112                    let tree = unsafe { tree.get_unchecked_mut() };
3113                    $insert(tree, factory.create(10));
3114
3115                    let replacement = factory.create(10);
3116                    let res = $insert_or_replace(tree, replacement);
3117                    assert!(res.is_some());
3118                    let old_item = res.unwrap();
3119                    assert_eq!($get_val(unsafe { old_item.as_target_ref() }), 10);
3120
3121                    let found = tree.find(&10);
3122                    assert!(found.is_some());
3123                    assert_eq!($get_val(found.unwrap()), 10);
3124
3125                    tree.clear();
3126                }
3127
3128                #[test]
3129                fn test_from_element() {
3130                    let mut factory = <$factory_type>::new();
3131                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3132                    let tree = unsafe { tree.get_unchecked_mut() };
3133
3134                    $insert(tree, factory.create(10));
3135                    $insert(tree, factory.create(20));
3136                    $insert(tree, factory.create(30));
3137
3138                    let target_ref = tree.find(&20).unwrap();
3139
3140                    let mut forward_iter: ForwardIterator<'_, i32, $ptr_type> = ForwardIterator::from_element(target_ref);
3141                    assert_eq!($get_val(forward_iter.next().unwrap()), 20);
3142                    assert_eq!($get_val(forward_iter.next().unwrap()), 30);
3143                    assert!(forward_iter.next().is_none());
3144
3145                    let mut reverse_iter: ReverseIterator<'_, i32, $ptr_type> = ReverseIterator::from_element(target_ref);
3146                    assert_eq!($get_val(reverse_iter.next().unwrap()), 20);
3147                    assert_eq!($get_val(reverse_iter.next().unwrap()), 10);
3148                    assert!(reverse_iter.next().is_none());
3149
3150                    tree.clear();
3151                }
3152
3153                #[test]
3154                fn test_cursor_at() {
3155                    let mut factory = <$factory_type>::new();
3156                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3157                    let tree = unsafe { tree.get_unchecked_mut() };
3158
3159                    $insert(tree, factory.create(10));
3160                    $insert(tree, factory.create(20));
3161                    $insert(tree, factory.create(30));
3162
3163                    let target_ptr = tree.find(&20).unwrap() as *const <$ptr_type as PtrTraits>::Target;
3164                    // SAFETY: target_ptr is a valid pointer to an object currently in the tree.
3165                    // Using a raw pointer bypasses the borrow checker, allowing us to obtain an unbound reference
3166                    // and borrow the tree mutably afterward.
3167                    let target_ref = unsafe { &*target_ptr };
3168
3169                    // Test read-only cursor_at
3170                    let cursor = unsafe { tree.cursor_at(target_ref) };
3171                    assert!(cursor.is_valid());
3172                    assert_eq!($get_val(cursor.get().unwrap()), 20);
3173                    assert_eq!($get_val(cursor.left().get().unwrap()), 10);
3174                    assert_eq!($get_val(cursor.right().get().unwrap()), 30);
3175
3176                    // Test mutable cursor_mut_at
3177                    let mut cursor_mut = unsafe { tree.cursor_mut_at(target_ref) };
3178                    assert_eq!($get_val(cursor_mut.get().unwrap()), 20);
3179
3180                    // Verify we can erase using the cursor returned by cursor_mut_at
3181                    let erased = cursor_mut.erase();
3182                    assert!(erased.is_some());
3183                    let val = erased.unwrap();
3184                    assert_eq!($get_val(unsafe { val.as_target_ref() }), 20);
3185
3186                    // Cursor should now be at the next element (30)
3187                    assert_eq!($get_val(cursor_mut.get().unwrap()), 30);
3188
3189                    tree.clear();
3190                }
3191
3192                #[test]
3193                fn test_empty_tree_cursors() {
3194                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3195                    // SAFETY: `tree` is never moved out of `tree` after pinning.
3196                    let tree = unsafe { tree.get_unchecked_mut() };
3197
3198                    // On an empty tree the root is null while the extremes are the sentinel;
3199                    // neither is a valid element.
3200                    assert!(!tree.root_cursor().is_valid());
3201                    assert!(tree.root_cursor().get().is_none());
3202                    assert!(!tree.front_cursor().is_valid());
3203                    assert!(tree.front_cursor().get().is_none());
3204                    assert!(!tree.back_cursor().is_valid());
3205                    assert!(tree.back_cursor().get().is_none());
3206                    assert!(tree.cursor_mut().get().is_none());
3207                    assert!(tree.find_cursor(&1).get().is_none());
3208                }
3209
3210                #[test]
3211                fn test_iterator_clone() {
3212                    let mut factory = <$factory_type>::new();
3213                    stack_pin_init!(let tree = WavlTree::<i32, $ptr_type>::new());
3214                    let tree = unsafe { tree.get_unchecked_mut() };
3215                    $insert(tree, factory.create(10));
3216                    $insert(tree, factory.create(20));
3217                    $insert(tree, factory.create(30));
3218
3219                    let mut iter = tree.iter();
3220                    assert_eq!($get_val(iter.next().unwrap()), 10);
3221
3222                    let mut cloned_iter = iter.clone();
3223
3224                    assert_eq!($get_val(iter.next().unwrap()), 20);
3225                    assert_eq!($get_val(iter.next().unwrap()), 30);
3226                    assert!(iter.next().is_none());
3227
3228                    assert_eq!($get_val(cloned_iter.next().unwrap()), 20);
3229                    assert_eq!($get_val(cloned_iter.next().unwrap()), 30);
3230                    assert!(cloned_iter.next().is_none());
3231
3232                    tree.clear();
3233                }
3234
3235                #[test]
3236                fn test_swap() {
3237                    let mut factory = <$factory_type>::new();
3238                    stack_pin_init!(let tree1 = WavlTree::<i32, $ptr_type>::new());
3239                    let tree1 = unsafe { tree1.get_unchecked_mut() };
3240                    stack_pin_init!(let tree2 = WavlTree::<i32, $ptr_type>::new());
3241                    let tree2 = unsafe { tree2.get_unchecked_mut() };
3242
3243                    $insert(tree1, factory.create(1));
3244                    $insert(tree1, factory.create(3));
3245
3246                    $insert(tree2, factory.create(2));
3247                    $insert(tree2, factory.create(4));
3248
3249                    tree1.swap(tree2);
3250
3251                    let mut iter1 = tree1.iter();
3252                    assert_eq!($get_val(iter1.next().unwrap()), 2);
3253                    assert_eq!($get_val(iter1.next().unwrap()), 4);
3254                    assert!(iter1.next().is_none());
3255
3256                    let mut iter2 = tree2.iter();
3257                    assert_eq!($get_val(iter2.next().unwrap()), 1);
3258                    assert_eq!($get_val(iter2.next().unwrap()), 3);
3259                    assert!(iter2.next().is_none());
3260
3261                    tree1.clear();
3262                    tree2.clear();
3263                }
3264            }
3265        };
3266    }
3267
3268    generate_tree_tests!(
3269        raw_ptr_tests,
3270        *mut TestObject,
3271        RawFactory<TestObject>,
3272        |p: &TestObject| p.value,
3273        |tree, obj| unsafe { WavlTree::<i32, *mut TestObject>::insert_raw(tree, obj) },
3274        |tree, obj| unsafe { WavlTree::<i32, *mut TestObject>::insert_or_find_raw(tree, obj) },
3275        |tree, obj| unsafe { WavlTree::<i32, *mut TestObject>::insert_or_replace_raw(tree, obj) }
3276    );
3277
3278    generate_tree_tests!(
3279        unique_ptr_tests,
3280        UniquePtr<UniqueTestObject>,
3281        UniqueFactory<UniqueTestObject>,
3282        |p: &UniqueTestObject| p.value,
3283        |tree, obj| WavlTree::<i32, UniquePtr<UniqueTestObject>>::insert(tree, obj),
3284        |tree, obj| WavlTree::<i32, UniquePtr<UniqueTestObject>>::insert_or_find(tree, obj),
3285        |tree, obj| WavlTree::<i32, UniquePtr<UniqueTestObject>>::insert_or_replace(tree, obj)
3286    );
3287
3288    generate_tree_tests!(
3289        ref_ptr_tests,
3290        RefPtr<RefTestObject>,
3291        RefFactory<RefTestObject>,
3292        |p: &RefTestObject| p.value,
3293        |tree, obj| WavlTree::<i32, RefPtr<RefTestObject>>::insert(tree, obj),
3294        |tree, obj| WavlTree::<i32, RefPtr<RefTestObject>>::insert_or_find(tree, obj),
3295        |tree, obj| WavlTree::<i32, RefPtr<RefTestObject>>::insert_or_replace(tree, obj)
3296    );
3297
3298    #[test]
3299    fn test_erase_by_raw_pointer() {
3300        stack_pin_init!(let tree = WavlTree::<i32, *mut TestObject, DefaultObjectTag, TrackingSize>::new());
3301        let tree = unsafe { tree.get_unchecked_mut() };
3302        let mut obj1 = TestObject::new(10);
3303        let mut obj2 = TestObject::new(20);
3304        let mut obj3 = TestObject::new(30);
3305
3306        unsafe {
3307            tree.insert_raw(core::ptr::addr_of_mut!(obj1));
3308            tree.insert_raw(core::ptr::addr_of_mut!(obj2));
3309            tree.insert_raw(core::ptr::addr_of_mut!(obj3));
3310        }
3311
3312        assert_eq!(tree.len(), 3);
3313
3314        // Erase obj2 directly
3315        let erased = unsafe { tree.erase_raw(core::ptr::addr_of_mut!(obj2)) };
3316        assert!(erased.is_some());
3317        assert_eq!(unsafe { &*erased.unwrap() }.value, 20);
3318        assert_eq!(tree.len(), 2);
3319
3320        let mut iter = tree.iter();
3321        assert_eq!(iter.next().unwrap().value, 10);
3322        assert_eq!(iter.next().unwrap().value, 30);
3323        assert!(iter.next().is_none());
3324
3325        tree.clear();
3326    }
3327
3328    #[test]
3329    fn test_clear_unsafe() {
3330        stack_pin_init!(let tree = WavlTree::<i32, *mut TestObject, DefaultObjectTag, TrackingSize>::new());
3331        let tree = unsafe { tree.get_unchecked_mut() };
3332        let mut obj1 = TestObject::new(10);
3333        let mut obj2 = TestObject::new(20);
3334        let mut obj3 = TestObject::new(30);
3335
3336        unsafe {
3337            tree.insert_raw(core::ptr::addr_of_mut!(obj1));
3338            tree.insert_raw(core::ptr::addr_of_mut!(obj2));
3339            tree.insert_raw(core::ptr::addr_of_mut!(obj3));
3340        }
3341
3342        assert_eq!(tree.len(), 3);
3343        assert!(!tree.is_empty());
3344
3345        tree.clear_unsafe();
3346
3347        assert_eq!(tree.len(), 0);
3348        assert!(tree.is_empty());
3349
3350        // Clean up the nodes manually so that they can be safely dropped.
3351        unsafe {
3352            (*obj1.get_node().parent.get()) = core::ptr::null_mut();
3353            (*obj1.get_node().left.get()) = core::ptr::null_mut();
3354            (*obj1.get_node().right.get()) = core::ptr::null_mut();
3355
3356            (*obj2.get_node().parent.get()) = core::ptr::null_mut();
3357            (*obj2.get_node().left.get()) = core::ptr::null_mut();
3358            (*obj2.get_node().right.get()) = core::ptr::null_mut();
3359
3360            (*obj3.get_node().parent.get()) = core::ptr::null_mut();
3361            (*obj3.get_node().left.get()) = core::ptr::null_mut();
3362            (*obj3.get_node().right.get()) = core::ptr::null_mut();
3363        }
3364    }
3365
3366    #[test]
3367    fn test_tracking_size() {
3368        stack_pin_init!(let tree = WavlTree::<i32, UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
3369        let tree = unsafe { tree.get_unchecked_mut() };
3370
3371        assert_eq!(tree.len(), 0);
3372        tree.insert(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
3373        assert_eq!(tree.len(), 1);
3374        tree.insert(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
3375        assert_eq!(tree.len(), 2);
3376        tree.pop_front();
3377        assert_eq!(tree.len(), 1);
3378        tree.clear();
3379        assert_eq!(tree.len(), 0);
3380    }
3381
3382    struct Tag2;
3383
3384    #[fbl::ref_counted]
3385    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
3386    #[repr(C)]
3387    struct MultiTreeObject {
3388        value: i32,
3389        #[wavl_node]
3390        node1: WavlTreeNode<MultiTreeObject>,
3391        #[wavl_node(tag = Tag2)]
3392        node2: WavlTreeNode<MultiTreeObject>,
3393    }
3394
3395    impl WavlTreeKeyable<i32> for MultiTreeObject {
3396        type Key<'a> = i32;
3397        fn get_key(&self) -> i32 {
3398            self.value
3399        }
3400    }
3401
3402    #[test]
3403    fn test_multiple_containers() {
3404        stack_pin_init!(let tree1 = WavlTree::<i32, RefPtr<MultiTreeObject>, DefaultObjectTag>::new());
3405        let tree1 = unsafe { tree1.get_unchecked_mut() };
3406        stack_pin_init!(let tree2 = WavlTree::<i32, RefPtr<MultiTreeObject>, Tag2>::new());
3407        let tree2 = unsafe { tree2.get_unchecked_mut() };
3408
3409        let obj1 = fbl::make_ref_counted!(MultiTreeObject {
3410            value: 10,
3411            node1: WavlTreeNode::new(),
3412            node2: WavlTreeNode::new(),
3413        })
3414        .unwrap();
3415
3416        let obj2 = fbl::make_ref_counted!(MultiTreeObject {
3417            value: 20,
3418            node1: WavlTreeNode::new(),
3419            node2: WavlTreeNode::new(),
3420        })
3421        .unwrap();
3422
3423        tree1.insert(obj1.clone());
3424        tree1.insert(obj2.clone());
3425
3426        tree2.insert(obj1.clone());
3427        tree2.insert(obj2.clone());
3428
3429        let mut iter1 = tree1.iter();
3430        assert_eq!(iter1.next().unwrap().value, 10);
3431        assert_eq!(iter1.next().unwrap().value, 20);
3432
3433        let mut iter2 = tree2.iter();
3434        assert_eq!(iter2.next().unwrap().value, 10);
3435        assert_eq!(iter2.next().unwrap().value, 20);
3436
3437        tree1.clear();
3438        tree2.clear();
3439    }
3440
3441    extern crate alloc;
3442    use alloc::boxed::Box;
3443    use alloc::sync::Arc;
3444    use alloc::vec::Vec;
3445    use core::sync::atomic::{AtomicUsize, Ordering};
3446
3447    struct Lfsr {
3448        core: u64,
3449    }
3450
3451    impl Lfsr {
3452        fn new(initial_core: u64) -> Self {
3453            Self { core: initial_core }
3454        }
3455
3456        fn set_core(&mut self, val: u64) {
3457            self.core = val;
3458        }
3459
3460        fn get_next(&mut self) -> u64 {
3461            let mut ret = 0u64;
3462            let mut flag = 1u64;
3463            let generator = 0xD800000000000000u64;
3464
3465            for _ in 0..(core::mem::size_of::<usize>() * 8) {
3466                let bit = (self.core & 1) != 0;
3467                self.core >>= 1;
3468                if bit {
3469                    self.core ^= generator;
3470                    ret |= flag;
3471                }
3472                flag <<= 1;
3473            }
3474
3475            ret
3476        }
3477    }
3478
3479    struct OpCounts {
3480        insert_ops: AtomicUsize,
3481        insert_promotes: AtomicUsize,
3482        insert_rotations: AtomicUsize,
3483        insert_double_rotations: AtomicUsize,
3484        insert_collisions: AtomicUsize,
3485        insert_replacements: AtomicUsize,
3486        insert_traversals: AtomicUsize,
3487        inspected_rotations: AtomicUsize,
3488        erase_ops: AtomicUsize,
3489        erase_demotes: AtomicUsize,
3490        erase_rotations: AtomicUsize,
3491        erase_double_rotations: AtomicUsize,
3492    }
3493
3494    impl OpCounts {
3495        const fn new() -> Self {
3496            Self {
3497                insert_ops: AtomicUsize::new(0),
3498                insert_promotes: AtomicUsize::new(0),
3499                insert_rotations: AtomicUsize::new(0),
3500                insert_double_rotations: AtomicUsize::new(0),
3501                insert_collisions: AtomicUsize::new(0),
3502                insert_replacements: AtomicUsize::new(0),
3503                insert_traversals: AtomicUsize::new(0),
3504                inspected_rotations: AtomicUsize::new(0),
3505                erase_ops: AtomicUsize::new(0),
3506                erase_demotes: AtomicUsize::new(0),
3507                erase_rotations: AtomicUsize::new(0),
3508                erase_double_rotations: AtomicUsize::new(0),
3509            }
3510        }
3511    }
3512
3513    #[derive(crate::WavlTreeContainable)]
3514    #[repr(C)]
3515    struct BalanceTestObj {
3516        key: u64,
3517        min_subtree_key: u64,
3518        max_subtree_key: u64,
3519        erase_deck_ptr: core::cell::Cell<*mut BalanceTestObj>,
3520        #[wavl_node(rank = i32)]
3521        node: WavlTreeNode<BalanceTestObj, i32>,
3522    }
3523
3524    impl BalanceTestObj {
3525        fn new(key: u64) -> Self {
3526            Self {
3527                key,
3528                min_subtree_key: 0,
3529                max_subtree_key: 0,
3530                erase_deck_ptr: core::cell::Cell::new(core::ptr::null_mut()),
3531                node: WavlTreeNode::new(),
3532            }
3533        }
3534
3535        fn swap_erase_deck_ptr(a: &BalanceTestObj, b: &BalanceTestObj) {
3536            let tmp = a.erase_deck_ptr.get();
3537            a.erase_deck_ptr.set(b.erase_deck_ptr.get());
3538            b.erase_deck_ptr.set(tmp);
3539        }
3540    }
3541
3542    impl WavlTreeKeyable<u64> for BalanceTestObj {
3543        type Key<'a> = u64;
3544        fn get_key(&self) -> u64 {
3545            self.key
3546        }
3547    }
3548
3549    struct WavlBalanceTestObserver {
3550        op_counts: Arc<OpCounts>,
3551    }
3552    impl WavlTreeObserver for WavlBalanceTestObserver {
3553        type Target = BalanceTestObj;
3554
3555        fn record_insert(&self, node: *mut BalanceTestObj) {
3556            self.op_counts.insert_ops.fetch_add(1, Ordering::Relaxed);
3557            unsafe {
3558                (*node).min_subtree_key = (*node).key;
3559                (*node).max_subtree_key = (*node).key;
3560            }
3561        }
3562
3563        fn record_insert_traverse(&self, node: *mut BalanceTestObj, ancestor: *mut BalanceTestObj) {
3564            self.op_counts.insert_traversals.fetch_add(1, Ordering::Relaxed);
3565            unsafe {
3566                (*ancestor).min_subtree_key =
3567                    core::cmp::min((*ancestor).min_subtree_key, (*node).key);
3568                (*ancestor).max_subtree_key =
3569                    core::cmp::max((*ancestor).max_subtree_key, (*node).key);
3570            }
3571        }
3572
3573        fn record_insert_collision(
3574            &self,
3575            _node: *mut BalanceTestObj,
3576            _collision: *mut BalanceTestObj,
3577        ) {
3578            self.op_counts.insert_collisions.fetch_add(1, Ordering::Relaxed);
3579        }
3580
3581        fn record_insert_replace(
3582            &self,
3583            node: *mut BalanceTestObj,
3584            replacement: *mut BalanceTestObj,
3585        ) {
3586            self.op_counts.insert_replacements.fetch_add(1, Ordering::Relaxed);
3587            unsafe {
3588                (*replacement).min_subtree_key = (*node).min_subtree_key;
3589                (*replacement).max_subtree_key = (*node).max_subtree_key;
3590            }
3591        }
3592
3593        fn record_insert_promote(&self) {
3594            self.op_counts.insert_promotes.fetch_add(1, Ordering::Relaxed);
3595        }
3596
3597        fn record_insert_rotation(&self) {
3598            self.op_counts.insert_rotations.fetch_add(1, Ordering::Relaxed);
3599        }
3600
3601        fn record_insert_double_rotation(&self) {
3602            self.op_counts.insert_double_rotations.fetch_add(1, Ordering::Relaxed);
3603        }
3604
3605        fn record_rotation(
3606            &self,
3607            pivot: *mut BalanceTestObj,
3608            lr_child: *mut BalanceTestObj,
3609            _rl_child: *mut BalanceTestObj,
3610            parent: *mut BalanceTestObj,
3611            sibling: *mut BalanceTestObj,
3612        ) {
3613            self.op_counts.inspected_rotations.fetch_add(1, Ordering::Relaxed);
3614            unsafe {
3615                (*pivot).min_subtree_key = (*parent).min_subtree_key;
3616                (*pivot).max_subtree_key = (*parent).max_subtree_key;
3617
3618                (*parent).min_subtree_key = (*parent).key;
3619                (*parent).max_subtree_key = (*parent).key;
3620
3621                if valid_sentinel_ptr(sibling) {
3622                    (*parent).min_subtree_key =
3623                        core::cmp::min((*parent).min_subtree_key, (*sibling).min_subtree_key);
3624                    (*parent).max_subtree_key =
3625                        core::cmp::max((*parent).max_subtree_key, (*sibling).max_subtree_key);
3626                }
3627                if valid_sentinel_ptr(lr_child) {
3628                    (*parent).min_subtree_key =
3629                        core::cmp::min((*parent).min_subtree_key, (*lr_child).min_subtree_key);
3630                    (*parent).max_subtree_key =
3631                        core::cmp::max((*parent).max_subtree_key, (*lr_child).max_subtree_key);
3632                }
3633            }
3634        }
3635
3636        fn record_erase(&self, _node: *mut BalanceTestObj, invalidated: *mut BalanceTestObj) {
3637            self.op_counts.erase_ops.fetch_add(1, Ordering::Relaxed);
3638            unsafe {
3639                let mut current = invalidated;
3640                while valid_sentinel_ptr(current) {
3641                    (*current).min_subtree_key = (*current).key;
3642                    (*current).max_subtree_key = (*current).key;
3643
3644                    let ns = (*current).get_node();
3645                    let left = ns.get_left();
3646                    if valid_sentinel_ptr(left) {
3647                        (*current).min_subtree_key =
3648                            core::cmp::min((*current).min_subtree_key, (*left).min_subtree_key);
3649                        (*current).max_subtree_key =
3650                            core::cmp::max((*current).max_subtree_key, (*left).max_subtree_key);
3651                    }
3652                    let right = ns.get_right();
3653                    if valid_sentinel_ptr(right) {
3654                        (*current).min_subtree_key =
3655                            core::cmp::min((*current).min_subtree_key, (*right).min_subtree_key);
3656                        (*current).max_subtree_key =
3657                            core::cmp::max((*current).max_subtree_key, (*right).max_subtree_key);
3658                    }
3659                    current = ns.get_parent();
3660                }
3661            }
3662        }
3663
3664        fn record_erase_demote(&self) {
3665            self.op_counts.erase_demotes.fetch_add(1, Ordering::Relaxed);
3666        }
3667
3668        fn record_erase_rotation(&self) {
3669            self.op_counts.erase_rotations.fetch_add(1, Ordering::Relaxed);
3670        }
3671
3672        fn record_erase_double_rotation(&self) {
3673            self.op_counts.erase_double_rotations.fetch_add(1, Ordering::Relaxed);
3674        }
3675
3676        fn verify_rank_rule(
3677            &self,
3678            node: *mut BalanceTestObj,
3679            _left_most: *mut BalanceTestObj,
3680            _right_most: *mut BalanceTestObj,
3681            _sentinel: *mut BalanceTestObj,
3682        ) {
3683            unsafe {
3684                let ns = (*node).get_node();
3685                let rank = ns.rank();
3686                assert!(rank >= 0, "All ranks must be non-negative.");
3687
3688                let left = ns.get_left();
3689                let right = ns.get_right();
3690
3691                if !valid_sentinel_ptr(left) && !valid_sentinel_ptr(right) {
3692                    assert_eq!(rank, 0i32, "Leaf nodes must have rank 0!");
3693                } else {
3694                    if valid_sentinel_ptr(left) {
3695                        let left_ns = (*left).get_node();
3696                        let delta = rank - left_ns.rank();
3697                        assert!(
3698                            delta >= 1 && delta <= 2,
3699                            "Left hand rank difference not in range [1, 2]"
3700                        );
3701                    }
3702
3703                    if valid_sentinel_ptr(right) {
3704                        let right_ns = (*right).get_node();
3705                        let delta = rank - right_ns.rank();
3706                        assert!(
3707                            delta >= 1 && delta <= 2,
3708                            "Right hand rank difference not in range [1, 2]"
3709                        );
3710                    }
3711                }
3712            }
3713        }
3714
3715        fn verify_balance(&self, size: usize, depth: usize) {
3716            if size > 0 {
3717                let log2_n = (size as f64).log2();
3718                let erase_ops = self.op_counts.erase_ops.load(Ordering::Relaxed);
3719                let scale = if erase_ops > 0 { 2.0 } else { 1.4404200904125564 };
3720                let max_depth = (log2_n * scale) as usize + 1;
3721                assert!(
3722                    max_depth >= depth,
3723                    "Depth bound exceeded! max_depth: {}, actual depth: {}",
3724                    max_depth,
3725                    depth
3726                );
3727
3728                let insert_rotations = self.op_counts.insert_rotations.load(Ordering::Relaxed);
3729                let insert_double_rotations =
3730                    self.op_counts.insert_double_rotations.load(Ordering::Relaxed);
3731                let insert_promotes = self.op_counts.insert_promotes.load(Ordering::Relaxed);
3732                let insert_ops = self.op_counts.insert_ops.load(Ordering::Relaxed);
3733
3734                let total_insert_rotations = insert_rotations + insert_double_rotations;
3735                assert!(
3736                    insert_promotes <= (3 * insert_ops) + (2 * erase_ops),
3737                    "#insert promotes must be <= (3 * #inserts) + (2 * #erases)"
3738                );
3739                assert!(
3740                    total_insert_rotations <= insert_ops,
3741                    "#insert_rotations must be <= #inserts"
3742                );
3743
3744                let erase_demotes = self.op_counts.erase_demotes.load(Ordering::Relaxed);
3745                let erase_rotations = self.op_counts.erase_rotations.load(Ordering::Relaxed);
3746                let erase_double_rotations =
3747                    self.op_counts.erase_double_rotations.load(Ordering::Relaxed);
3748
3749                let total_erase_rotations = erase_rotations + erase_double_rotations;
3750                assert!(erase_demotes <= erase_ops, "#erase demotes must be <= #erases");
3751                assert!(total_erase_rotations <= erase_ops, "#erase_rotations must be <= #erases");
3752
3753                let inspected_rotations =
3754                    self.op_counts.inspected_rotations.load(Ordering::Relaxed);
3755                let total_inspected_rotations = insert_rotations
3756                    + erase_rotations
3757                    + 2 * insert_double_rotations
3758                    + 2 * erase_double_rotations;
3759                assert_eq!(
3760                    total_inspected_rotations, inspected_rotations,
3761                    "#inspected rotations must be == #rotations"
3762                );
3763            }
3764        }
3765    }
3766
3767    struct WavlTreeChecker;
3768    impl WavlTreeChecker {
3769        fn verify_parent_back_links<K, P, Tag, S, O>(cursor: Cursor<'_, K, P, Tag, S, O>)
3770        where
3771            P: PtrTraits,
3772            P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3773            K: Ord,
3774            S: SizeTracker,
3775            O: WavlTreeObserver<Target = P::Target>,
3776        {
3777            assert!(cursor.is_valid());
3778            let left = cursor.left();
3779            if left.is_valid() {
3780                assert_eq!(
3781                    cursor.as_raw_ptr(),
3782                    left.parent().as_raw_ptr(),
3783                    "Corrupt left-side parent back-link!"
3784                );
3785            }
3786
3787            let right = cursor.right();
3788            if right.is_valid() {
3789                assert_eq!(
3790                    cursor.as_raw_ptr(),
3791                    right.parent().as_raw_ptr(),
3792                    "Corrupt right-side parent back-link!"
3793                );
3794            }
3795        }
3796
3797        fn sanity_check<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>)
3798        where
3799            P: PtrTraits,
3800            P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3801            K: Ord,
3802            S: SizeTracker,
3803            O: WavlTreeObserver<Target = P::Target>,
3804        {
3805            let is_empty = tree.is_empty();
3806            let root = tree.root_cursor();
3807            let front = tree.front_cursor();
3808            let back = tree.back_cursor();
3809
3810            let sentinel_ptr =
3811                if is_empty { front.as_raw_ptr() } else { front.left().as_raw_ptr() };
3812
3813            if is_empty {
3814                assert!(!root.is_valid());
3815                assert!(!front.is_valid());
3816                assert!(!back.is_valid());
3817                if S::IS_TRACKING {
3818                    assert_eq!(tree.len(), 0);
3819                }
3820            } else {
3821                assert!(root.is_valid());
3822                assert!(front.is_valid());
3823                assert!(back.is_valid());
3824                assert!(!front.left().is_valid());
3825                assert!(!back.right().is_valid());
3826                if S::IS_TRACKING {
3827                    assert!(tree.len() > 0);
3828                }
3829            }
3830
3831            let mut cur_depth = 0;
3832            let mut depth = 0;
3833            let mut size = 0;
3834
3835            let mut cursor = root;
3836
3837            while cursor.is_valid() {
3838                Self::verify_parent_back_links(cursor);
3839                cur_depth += 1;
3840
3841                let left = cursor.left();
3842                if !left.is_valid() {
3843                    break;
3844                }
3845                cursor = left;
3846            }
3847
3848            while cursor.is_valid() {
3849                if depth < cur_depth {
3850                    depth = cur_depth;
3851                }
3852                size += 1;
3853
3854                Self::verify_parent_back_links(cursor);
3855                tree.observer.verify_rank_rule(
3856                    cursor.as_raw_ptr(),
3857                    front.as_raw_ptr(),
3858                    back.as_raw_ptr(),
3859                    sentinel_ptr,
3860                );
3861
3862                let right = cursor.right();
3863                if right.is_valid() {
3864                    cur_depth += 1;
3865                    cursor = right;
3866                    Self::verify_parent_back_links(cursor);
3867
3868                    loop {
3869                        let left = cursor.left();
3870                        if !left.is_valid() {
3871                            break;
3872                        }
3873                        cur_depth += 1;
3874                        cursor = left;
3875                        Self::verify_parent_back_links(cursor);
3876                    }
3877                    continue;
3878                }
3879
3880                let mut parent = cursor.parent();
3881                let mut keep_going = false;
3882                while parent.is_valid() {
3883                    let is_left = parent.left() == cursor;
3884                    let is_right = parent.right() == cursor;
3885
3886                    assert!(is_left != is_right);
3887                    assert!(is_left || is_right);
3888
3889                    cursor = parent;
3890                    cur_depth -= 1;
3891
3892                    if is_left {
3893                        keep_going = true;
3894                        break;
3895                    }
3896
3897                    parent = parent.parent();
3898                }
3899
3900                if !keep_going {
3901                    break;
3902                }
3903            }
3904
3905            if S::IS_TRACKING {
3906                assert_eq!(tree.len(), size);
3907            }
3908            tree.observer.verify_balance(size, depth);
3909        }
3910    }
3911
3912    fn shuffle_erase_deck(objects: &[Box<BalanceTestObj>], rng: &mut Lfsr, size: usize) {
3913        for i in (2..size).rev() {
3914            let ndx = (rng.get_next() as usize) % i;
3915            if ndx != i {
3916                BalanceTestObj::swap_erase_deck_ptr(&objects[i], &objects[ndx]);
3917            }
3918        }
3919    }
3920
3921    fn check_augmented_invariants<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>)
3922    where
3923        P: PtrTraits,
3924        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3925        K: Ord,
3926        S: SizeTracker,
3927        O: WavlTreeObserver<Target = P::Target>,
3928    {
3929        if tree.is_empty() {
3930            return;
3931        }
3932        let root = tree.root_cursor().as_raw_ptr() as *mut BalanceTestObj;
3933        let left = tree.front_cursor().as_raw_ptr() as *mut BalanceTestObj;
3934        let right = tree.back_cursor().as_raw_ptr() as *mut BalanceTestObj;
3935
3936        unsafe {
3937            assert_eq!((*root).min_subtree_key, (*left).key, "Min subtree key invariant violated!");
3938            assert_eq!(
3939                (*root).max_subtree_key,
3940                (*right).key,
3941                "Max subtree key invariant violated!"
3942            );
3943        }
3944    }
3945
3946    fn check_iterators<K, P, Tag, S, O>(tree: &WavlTree<K, P, Tag, S, O>)
3947    where
3948        P: PtrTraits,
3949        P::Target: WavlTreeContainable<P::Target, Tag> + WavlTreeKeyable<K>,
3950        K: Ord,
3951        S: SizeTracker,
3952        O: WavlTreeObserver<Target = P::Target>,
3953    {
3954        if tree.is_empty() {
3955            return;
3956        }
3957        let root = tree.root_cursor();
3958        let left_most = tree.front_cursor();
3959        let right_most = tree.back_cursor();
3960
3961        let mut left_cursor = root;
3962        let mut right_cursor = root;
3963        let mut i = 0;
3964
3965        let limit = if S::IS_TRACKING { tree.len() } else { 10000 };
3966
3967        while (left_cursor != left_most || right_cursor != right_most) && i < limit {
3968            assert!(left_cursor.is_valid());
3969            if left_cursor == left_most {
3970                assert!(!left_cursor.left().is_valid());
3971            } else {
3972                left_cursor = left_cursor.left();
3973            }
3974
3975            assert!(right_cursor.is_valid());
3976            if right_cursor == right_most {
3977                assert!(!right_cursor.right().is_valid());
3978            } else {
3979                right_cursor = right_cursor.right();
3980            }
3981
3982            i += 1;
3983        }
3984
3985        assert_eq!(left_cursor, left_most);
3986        assert_eq!(right_cursor, right_most);
3987
3988        let limit = i;
3989        left_cursor = left_most;
3990        right_cursor = right_most;
3991        i = 0;
3992
3993        while (left_cursor != root || right_cursor != root) && i < limit {
3994            assert!(left_cursor.is_valid());
3995            if left_cursor == root {
3996                assert!(!left_cursor.parent().is_valid());
3997            } else {
3998                left_cursor = left_cursor.parent();
3999            }
4000
4001            assert!(right_cursor.is_valid());
4002            if right_cursor == root {
4003                assert!(!right_cursor.parent().is_valid());
4004            } else {
4005                right_cursor = right_cursor.parent();
4006            }
4007
4008            i += 1;
4009        }
4010
4011        assert_eq!(left_cursor, root);
4012        assert_eq!(right_cursor, root);
4013    }
4014
4015    #[test]
4016    fn test_balance_and_invariants() {
4017        let seeds = [0xe87e1062fc1f4f80u64, 0x03d6bffb124b4918u64, 0x8f7d83e8d10b4765u64];
4018        let test_size = 128;
4019        let replacement_count = test_size / 8;
4020        let mut rng = Lfsr::new(1);
4021
4022        for seed_ndx in 0..seeds.len() {
4023            let seed = seeds[seed_ndx];
4024            rng.set_core(seed);
4025
4026            let op_counts = Arc::new(OpCounts::new());
4027            let observer = WavlBalanceTestObserver { op_counts: Arc::clone(&op_counts) };
4028
4029            stack_pin_init!(let tree = WavlTree::<u64, *mut BalanceTestObj, DefaultObjectTag, TrackingSize, WavlBalanceTestObserver>::new_with_observer(observer));
4030            let tree = unsafe { tree.get_unchecked_mut() };
4031
4032            let mut objects = Vec::with_capacity(test_size);
4033            let mut replacements = Vec::with_capacity(replacement_count);
4034
4035            match seed_ndx {
4036                0 => {
4037                    for i in 0..test_size {
4038                        let obj = Box::new(BalanceTestObj::new(i as u64));
4039                        let raw = &*obj as *const BalanceTestObj as *mut BalanceTestObj;
4040                        obj.erase_deck_ptr.set(raw);
4041                        objects.push(obj);
4042
4043                        if i < replacement_count {
4044                            let rep = Box::new(BalanceTestObj::new(i as u64));
4045                            let raw = &*rep as *const BalanceTestObj as *mut BalanceTestObj;
4046                            rep.erase_deck_ptr.set(raw);
4047                            replacements.push(rep);
4048                        }
4049                    }
4050                }
4051                1 => {
4052                    for i in 0..test_size {
4053                        let obj = Box::new(BalanceTestObj::new((test_size - i) as u64));
4054                        let raw = &*obj as *const BalanceTestObj as *mut BalanceTestObj;
4055                        obj.erase_deck_ptr.set(raw);
4056                        objects.push(obj);
4057
4058                        if i < replacement_count {
4059                            let rep = Box::new(BalanceTestObj::new((test_size - i) as u64));
4060                            let raw = &*rep as *const BalanceTestObj as *mut BalanceTestObj;
4061                            rep.erase_deck_ptr.set(raw);
4062                            replacements.push(rep);
4063                        }
4064                    }
4065                }
4066                _ => {
4067                    for i in 0..test_size {
4068                        let val = rng.get_next();
4069                        let obj = Box::new(BalanceTestObj::new(val));
4070                        let raw = &*obj as *const BalanceTestObj as *mut BalanceTestObj;
4071                        obj.erase_deck_ptr.set(raw);
4072                        objects.push(obj);
4073
4074                        if i < replacement_count {
4075                            let rep = Box::new(BalanceTestObj::new(val));
4076                            let raw = &*rep as *const BalanceTestObj as *mut BalanceTestObj;
4077                            rep.erase_deck_ptr.set(raw);
4078                            replacements.push(rep);
4079                        }
4080                    }
4081                }
4082            }
4083
4084            // 1. Insert all objects
4085            for i in 0..test_size {
4086                unsafe {
4087                    check_augmented_invariants(tree);
4088                    WavlTreeChecker::sanity_check(tree);
4089                    let raw = &mut *objects[i] as *mut BalanceTestObj;
4090                    tree.insert_raw(raw);
4091                    check_augmented_invariants(tree);
4092                    WavlTreeChecker::sanity_check(tree);
4093                }
4094            }
4095
4096            check_iterators(tree);
4097
4098            // 2. Collide replacements
4099            for i in 0..replacement_count {
4100                unsafe {
4101                    check_augmented_invariants(tree);
4102                    WavlTreeChecker::sanity_check(tree);
4103                    let raw = &mut *replacements[i] as *mut BalanceTestObj;
4104                    assert!(tree.insert_or_find_raw(raw).is_err());
4105                    check_augmented_invariants(tree);
4106                    WavlTreeChecker::sanity_check(tree);
4107                }
4108            }
4109
4110            // 3. Replace original nodes with replacements
4111            for i in 0..replacement_count {
4112                unsafe {
4113                    check_augmented_invariants(tree);
4114                    WavlTreeChecker::sanity_check(tree);
4115                    let raw = &mut *replacements[i] as *mut BalanceTestObj;
4116                    assert!(tree.insert_or_replace_raw(raw).is_some());
4117                    check_augmented_invariants(tree);
4118                    WavlTreeChecker::sanity_check(tree);
4119                }
4120            }
4121
4122            check_iterators(tree);
4123
4124            // 4. Swap them back
4125            for i in 0..replacement_count {
4126                unsafe {
4127                    check_augmented_invariants(tree);
4128                    WavlTreeChecker::sanity_check(tree);
4129                    let raw = &mut *objects[i] as *mut BalanceTestObj;
4130                    assert!(tree.insert_or_replace_raw(raw).is_some());
4131                    check_augmented_invariants(tree);
4132                    WavlTreeChecker::sanity_check(tree);
4133                }
4134            }
4135
4136            check_iterators(tree);
4137
4138            // Shuffle erase deck
4139            shuffle_erase_deck(&objects, &mut rng, test_size);
4140
4141            // 5. Erase half the elements
4142            for i in 0..(test_size / 2) {
4143                unsafe {
4144                    check_augmented_invariants(tree);
4145                    WavlTreeChecker::sanity_check(tree);
4146                    let raw_target = objects[i].erase_deck_ptr.get();
4147                    let erased = tree.erase_raw(raw_target);
4148                    assert!(erased.is_some());
4149                    assert_eq!(erased.unwrap(), raw_target);
4150                    check_augmented_invariants(tree);
4151                    WavlTreeChecker::sanity_check(tree);
4152                }
4153            }
4154
4155            check_iterators(tree);
4156
4157            // 6. Put them back
4158            for i in 0..(test_size / 2) {
4159                unsafe {
4160                    check_augmented_invariants(tree);
4161                    WavlTreeChecker::sanity_check(tree);
4162                    let raw_target = objects[i].erase_deck_ptr.get();
4163                    tree.insert_raw(raw_target);
4164                    check_augmented_invariants(tree);
4165                    WavlTreeChecker::sanity_check(tree);
4166                }
4167            }
4168
4169            check_iterators(tree);
4170
4171            // Shuffle erase deck again
4172            shuffle_erase_deck(&objects, &mut rng, test_size);
4173
4174            // 7. Erase everything
4175            for i in 0..test_size {
4176                unsafe {
4177                    check_augmented_invariants(tree);
4178                    WavlTreeChecker::sanity_check(tree);
4179                    let raw_target = objects[i].erase_deck_ptr.get();
4180                    let erased = tree.erase_raw(raw_target);
4181                    assert!(erased.is_some());
4182                    assert_eq!(erased.unwrap(), raw_target);
4183                    check_augmented_invariants(tree);
4184                    WavlTreeChecker::sanity_check(tree);
4185                }
4186            }
4187
4188            check_iterators(tree);
4189            assert_eq!(tree.size.get(), 0);
4190
4191            assert!(op_counts.insert_ops.load(Ordering::Relaxed) > 0);
4192            assert!(op_counts.insert_promotes.load(Ordering::Relaxed) > 0);
4193            assert!(op_counts.insert_rotations.load(Ordering::Relaxed) > 0);
4194            assert!(op_counts.insert_traversals.load(Ordering::Relaxed) > 0);
4195            assert!(op_counts.erase_ops.load(Ordering::Relaxed) > 0);
4196            assert!(op_counts.erase_demotes.load(Ordering::Relaxed) > 0);
4197            assert!(op_counts.erase_rotations.load(Ordering::Relaxed) > 0);
4198        }
4199    }
4200
4201    // WavlTree FFI Declarations
4202    unsafe extern "C" {
4203        // UniqueTree Helpers
4204        fn cpp_create_unique_tree() -> *mut c_void;
4205        fn cpp_destroy_unique_tree(tree: *mut c_void);
4206        fn cpp_unique_tree_insert(tree: *mut c_void, item: *mut c_void);
4207        fn cpp_unique_tree_erase(tree: *mut c_void, key: i32) -> *mut c_void;
4208        fn cpp_unique_tree_find(tree: *mut c_void, key: i32) -> *mut c_void;
4209        fn cpp_unique_tree_is_empty(tree: *mut c_void) -> bool;
4210
4211        // RefTree Helpers
4212        fn cpp_create_ref_tree() -> *mut c_void;
4213        fn cpp_destroy_ref_tree(tree: *mut c_void);
4214        fn cpp_ref_tree_insert(tree: *mut c_void, item: *mut c_void);
4215        fn cpp_ref_tree_erase(tree: *mut c_void, key: i32) -> *mut c_void;
4216        fn cpp_ref_tree_find(tree: *mut c_void, key: i32) -> *mut c_void;
4217        fn cpp_ref_tree_is_empty(tree: *mut c_void) -> bool;
4218
4219        // SharedUniqueObject Helpers (Defined in intrusive_container_test_support.cc)
4220        fn cpp_create_unique_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
4221        fn cpp_get_unique_object_value(obj: *mut c_void) -> i32;
4222
4223        // SharedRefObject Helpers (Defined in intrusive_container_test_support.cc)
4224        fn cpp_create_ref_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
4225        fn cpp_get_ref_object_value(obj: *mut c_void) -> i32;
4226    }
4227
4228    #[test]
4229    fn test_interop_rust_tree_cpp_unique_objects() {
4230        use core::sync::atomic::{AtomicBool, Ordering};
4231
4232        let destroyed1 = AtomicBool::new(false);
4233        let destroyed2 = AtomicBool::new(false);
4234
4235        unsafe {
4236            stack_pin_init!(let tree = WavlTree::<i32, UniquePtr<SharedUniqueObject>>::new());
4237            let tree = tree.get_unchecked_mut();
4238
4239            let cpp_raw1 = cpp_create_unique_object(10, destroyed1.as_ptr() as *mut bool);
4240            let cpp_raw2 = cpp_create_unique_object(20, destroyed2.as_ptr() as *mut bool);
4241
4242            let obj1 = UniquePtr::from_raw(cpp_raw1 as *mut SharedUniqueObject);
4243            let obj2 = UniquePtr::from_raw(cpp_raw2 as *mut SharedUniqueObject);
4244
4245            tree.insert(obj1);
4246            tree.insert(obj2);
4247
4248            assert!(!destroyed1.load(Ordering::Relaxed));
4249            assert!(!destroyed2.load(Ordering::Relaxed));
4250
4251            // Find one
4252            let found = tree.find(&10);
4253            assert!(found.is_some());
4254            assert_eq!(found.unwrap().value, 10);
4255
4256            // Erase one
4257            let popped = tree.erase(&20);
4258            assert!(popped.is_some());
4259            assert_eq!(popped.as_ref().unwrap().value, 20);
4260
4261            // Drop popped -> should destroy in C++!
4262            drop(popped);
4263            assert!(!destroyed1.load(Ordering::Relaxed));
4264            assert!(destroyed2.load(Ordering::Relaxed));
4265
4266            // Drop tree -> should destroy remaining in C++!
4267        }
4268        assert!(destroyed1.load(Ordering::Relaxed));
4269    }
4270
4271    #[test]
4272    fn test_interop_cpp_tree_rust_unique_objects() {
4273        use alloc::sync::Arc;
4274        use core::sync::atomic::{AtomicBool, Ordering};
4275
4276        let destroyed1 = Arc::new(AtomicBool::new(false));
4277        let destroyed2 = Arc::new(AtomicBool::new(false));
4278
4279        unsafe {
4280            let cpp_tree = cpp_create_unique_tree();
4281            assert!(cpp_unique_tree_is_empty(cpp_tree));
4282
4283            let obj1 = UniquePtr::try_new(SharedUniqueObject::new(10)).unwrap();
4284            let obj2 = UniquePtr::try_new(SharedUniqueObject::new(20)).unwrap();
4285
4286            // Set destruction flags
4287            let raw1 = UniquePtr::as_ptr(&obj1) as *mut SharedUniqueObject;
4288            (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
4289            let raw2 = UniquePtr::as_ptr(&obj2) as *mut SharedUniqueObject;
4290            (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
4291
4292            // Push to C++ tree (transfers ownership)
4293            cpp_unique_tree_insert(cpp_tree, UniquePtr::into_raw(obj1) as *mut c_void);
4294            cpp_unique_tree_insert(cpp_tree, UniquePtr::into_raw(obj2) as *mut c_void);
4295
4296            assert!(!destroyed1.load(Ordering::Relaxed));
4297            assert!(!destroyed2.load(Ordering::Relaxed));
4298
4299            // Find in C++
4300            let found = cpp_unique_tree_find(cpp_tree, 10);
4301            assert!(!found.is_null());
4302            assert_eq!(cpp_get_unique_object_value(found), 10);
4303
4304            // Erase one from C++
4305            let popped = cpp_unique_tree_erase(cpp_tree, 20);
4306            assert!(!popped.is_null());
4307            assert_eq!(cpp_get_unique_object_value(popped), 20);
4308
4309            // Convert back to Rust UniquePtr and drop -> should free in Rust!
4310            let popped_rust = UniquePtr::from_raw(popped as *mut SharedUniqueObject);
4311            drop(popped_rust);
4312            assert!(!destroyed1.load(Ordering::Relaxed));
4313            assert!(destroyed2.load(Ordering::Relaxed));
4314
4315            // Destroy C++ tree -> should destroy remaining in Rust!
4316            cpp_destroy_unique_tree(cpp_tree);
4317        }
4318        assert!(destroyed1.load(Ordering::Relaxed));
4319    }
4320
4321    #[test]
4322    fn test_interop_rust_tree_cpp_ref_objects() {
4323        use core::sync::atomic::{AtomicBool, Ordering};
4324
4325        let destroyed1 = AtomicBool::new(false);
4326        let destroyed2 = AtomicBool::new(false);
4327
4328        unsafe {
4329            stack_pin_init!(let tree = WavlTree::<i32, RefPtr<SharedRefObject>>::new());
4330            let tree = tree.get_unchecked_mut();
4331
4332            let cpp_raw1 = cpp_create_ref_object(10, destroyed1.as_ptr() as *mut bool);
4333            let cpp_raw2 = cpp_create_ref_object(20, destroyed2.as_ptr() as *mut bool);
4334
4335            let obj1 = RefPtr::from_raw(cpp_raw1 as *mut SharedRefObject);
4336            let obj2 = RefPtr::from_raw(cpp_raw2 as *mut SharedRefObject);
4337
4338            tree.insert(obj1);
4339            tree.insert(obj2);
4340
4341            assert!(!destroyed1.load(Ordering::Relaxed));
4342            assert!(!destroyed2.load(Ordering::Relaxed));
4343
4344            // Find one
4345            let found = tree.find(&10);
4346            assert!(found.is_some());
4347            assert_eq!(found.unwrap().value, 10);
4348
4349            // Erase one
4350            let popped = tree.erase(&20);
4351            assert!(popped.is_some());
4352            assert_eq!(popped.as_ref().unwrap().value, 20);
4353
4354            // Drop popped -> should destroy in C++!
4355            drop(popped);
4356            assert!(!destroyed1.load(Ordering::Relaxed));
4357            assert!(destroyed2.load(Ordering::Relaxed));
4358
4359            // Drop tree -> should destroy remaining in C++!
4360        }
4361        assert!(destroyed1.load(Ordering::Relaxed));
4362    }
4363
4364    #[test]
4365    fn test_interop_cpp_tree_rust_ref_objects() {
4366        use alloc::sync::Arc;
4367        use core::sync::atomic::{AtomicBool, Ordering};
4368
4369        let destroyed1 = Arc::new(AtomicBool::new(false));
4370        let destroyed2 = Arc::new(AtomicBool::new(false));
4371
4372        unsafe {
4373            let cpp_tree = cpp_create_ref_tree();
4374            assert!(cpp_ref_tree_is_empty(cpp_tree));
4375
4376            let obj1 = SharedRefObject::new_ref_counted(10);
4377            let obj2 = SharedRefObject::new_ref_counted(20);
4378
4379            // Set destruction flags
4380            let raw1 = RefPtr::as_ptr(&obj1) as *mut SharedRefObject;
4381            (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
4382            let raw2 = RefPtr::as_ptr(&obj2) as *mut SharedRefObject;
4383            (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
4384
4385            // Insert to C++ tree (transfers ownership)
4386            cpp_ref_tree_insert(
4387                cpp_tree,
4388                RefPtr::into_raw(obj1) as *mut SharedRefObject as *mut c_void,
4389            );
4390            cpp_ref_tree_insert(
4391                cpp_tree,
4392                RefPtr::into_raw(obj2) as *mut SharedRefObject as *mut c_void,
4393            );
4394
4395            assert!(!destroyed1.load(Ordering::Relaxed));
4396            assert!(!destroyed2.load(Ordering::Relaxed));
4397
4398            // Find in C++
4399            let found = cpp_ref_tree_find(cpp_tree, 10);
4400            assert!(!found.is_null());
4401            assert_eq!(cpp_get_ref_object_value(found), 10);
4402
4403            // Erase one from C++
4404            let popped = cpp_ref_tree_erase(cpp_tree, 20);
4405            assert!(!popped.is_null());
4406            assert_eq!(cpp_get_ref_object_value(popped), 20);
4407
4408            // Convert back to Rust RefPtr and drop -> should free in Rust!
4409            let popped_rust = RefPtr::from_raw(popped as *mut SharedRefObject);
4410            drop(popped_rust);
4411            assert!(!destroyed1.load(Ordering::Relaxed));
4412            assert!(destroyed2.load(Ordering::Relaxed));
4413
4414            // Destroy C++ tree -> should destroy remaining in Rust!
4415            cpp_destroy_ref_tree(cpp_tree);
4416        }
4417        assert!(destroyed1.load(Ordering::Relaxed));
4418    }
4419
4420    #[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
4421    struct LargeKey {
4422        name: [u8; 32],
4423    }
4424
4425    #[derive(crate::WavlTreeContainable, crate::Recyclable)]
4426    struct TestRefKeyObject {
4427        key: LargeKey,
4428        #[wavl_node]
4429        node: WavlTreeNode<TestRefKeyObject>,
4430    }
4431
4432    impl TestRefKeyObject {
4433        fn new(name: [u8; 32]) -> Self {
4434            Self { key: LargeKey { name }, node: WavlTreeNode::new() }
4435        }
4436    }
4437
4438    impl WavlTreeKeyable<LargeKey> for TestRefKeyObject {
4439        type Key<'a> = &'a LargeKey;
4440        fn get_key(&self) -> &LargeKey {
4441            &self.key
4442        }
4443    }
4444
4445    #[test]
4446    fn test_by_reference_key() {
4447        use crate::UniquePtr;
4448
4449        type TestTree = WavlTree<LargeKey, UniquePtr<TestRefKeyObject>>;
4450        stack_pin_init!(let tree = TestTree::new());
4451        let tree = unsafe { tree.get_unchecked_mut() };
4452
4453        let mut key1 = [0u8; 32];
4454        key1[0] = 10;
4455        let mut key2 = [0u8; 32];
4456        key2[0] = 20;
4457
4458        let obj1 = UniquePtr::try_new(TestRefKeyObject::new(key1)).unwrap();
4459        let obj2 = UniquePtr::try_new(TestRefKeyObject::new(key2)).unwrap();
4460        tree.insert(obj1);
4461        tree.insert(obj2);
4462
4463        let query = LargeKey { name: key1 };
4464        let found = tree.find(&query);
4465        assert!(found.is_some());
4466        assert_eq!(found.unwrap().key, query);
4467
4468        let erased = tree.erase(&query);
4469        assert!(erased.is_some());
4470        assert_eq!(erased.unwrap().key, query);
4471    }
4472
4473    #[derive(WavlTreeContainable, Recyclable)]
4474    struct TestAugmentedObject {
4475        value: i32,
4476        subtree_sum: core::cell::Cell<i32>,
4477        #[wavl_node]
4478        node: WavlTreeNode<TestAugmentedObject>,
4479    }
4480
4481    impl TestAugmentedObject {
4482        fn new(value: i32) -> Self {
4483            Self { value, subtree_sum: core::cell::Cell::new(0), node: WavlTreeNode::new() }
4484        }
4485    }
4486
4487    impl WavlTreeKeyable<i32> for TestAugmentedObject {
4488        type Key<'a> = i32;
4489        fn get_key(&self) -> i32 {
4490            self.value
4491        }
4492    }
4493
4494    struct SubtreeSumTraits;
4495    impl WavlTreeAugmentedInvariantObserverTraits for SubtreeSumTraits {
4496        type Target = TestAugmentedObject;
4497        type Value = i32;
4498
4499        fn get_node_value(node: &Self::Target) -> Self::Value {
4500            node.value
4501        }
4502
4503        fn get_subtree_value(node: &Self::Target) -> Self::Value {
4504            node.subtree_sum.get()
4505        }
4506
4507        fn combine_values(a: Self::Value, b: Self::Value) -> Self::Value {
4508            a + b
4509        }
4510
4511        fn set_subtree_value(node: &Self::Target, val: Self::Value) {
4512            node.subtree_sum.set(val);
4513        }
4514
4515        fn reset_subtree_value(node: &Self::Target) {
4516            node.subtree_sum.set(0);
4517        }
4518    }
4519
4520    #[test]
4521    fn test_augmented_invariant_observer() {
4522        type TestObserver = WavlTreeAugmentedInvariantObserver<DefaultObjectTag, SubtreeSumTraits>;
4523        type TestTree = WavlTree<
4524            i32,
4525            UniquePtr<TestAugmentedObject>,
4526            DefaultObjectTag,
4527            TrackingSize,
4528            TestObserver,
4529        >;
4530
4531        stack_pin_init!(let tree = TestTree::new_with_observer(TestObserver::default()));
4532        let tree = unsafe { tree.get_unchecked_mut() };
4533
4534        // Helper to verify subtree sums recursively
4535        fn verify_subtree_sums(node: *mut TestAugmentedObject) -> i32 {
4536            if !valid_sentinel_ptr(node) {
4537                return 0;
4538            }
4539            let node_ref = unsafe { &*node };
4540            let ns = node_ref.get_node();
4541            let left_sum = verify_subtree_sums(ns.get_left());
4542            let right_sum = verify_subtree_sums(ns.get_right());
4543            let expected_sum = node_ref.value + left_sum + right_sum;
4544            assert_eq!(
4545                node_ref.subtree_sum.get(),
4546                expected_sum,
4547                "Subtree sum mismatch at node {}",
4548                node_ref.value
4549            );
4550            expected_sum
4551        }
4552
4553        // Insert some nodes
4554        let values = [10, 20, 5, 15, 25, 2, 7];
4555        for &val in &values {
4556            let obj = UniquePtr::try_new(TestAugmentedObject::new(val)).unwrap();
4557            tree.insert(obj);
4558            // Verify after each insert
4559            if !tree.root.is_null() {
4560                verify_subtree_sums(tree.root);
4561            }
4562        }
4563
4564        // Verify final sum at root
4565        let expected_total_sum: i32 = values.iter().sum();
4566        assert_eq!(unsafe { &*tree.root }.subtree_sum.get(), expected_total_sum);
4567
4568        // Erase some nodes
4569        let to_erase = [15, 5, 20];
4570        let mut current_sum = expected_total_sum;
4571        for &val in &to_erase {
4572            let erased = tree.erase(&val);
4573            assert!(erased.is_some());
4574            assert_eq!(erased.as_ref().unwrap().value, val);
4575            current_sum -= val;
4576            if !tree.root.is_null() {
4577                assert_eq!(unsafe { &*tree.root }.subtree_sum.get(), current_sum);
4578                verify_subtree_sums(tree.root);
4579            }
4580        }
4581    }
4582
4583    #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
4584    struct NonCommutativeVal {
4585        hash: u64,
4586        len: u32,
4587    }
4588
4589    impl NonCommutativeVal {
4590        fn single(val: i32) -> Self {
4591            Self { hash: (val as u64) & 0xffff, len: 1 }
4592        }
4593
4594        fn combine(left: Self, right: Self) -> Self {
4595            if left.len == 0 {
4596                return right;
4597            }
4598            if right.len == 0 {
4599                return left;
4600            }
4601            let mut power = 1u64;
4602            for _ in 0..right.len {
4603                power = power.wrapping_mul(31);
4604            }
4605            Self {
4606                hash: left.hash.wrapping_mul(power).wrapping_add(right.hash),
4607                len: left.len + right.len,
4608            }
4609        }
4610    }
4611
4612    #[derive(WavlTreeContainable, Recyclable)]
4613    struct TestNonCommutativeObject {
4614        value: i32,
4615        subtree_val: core::cell::Cell<NonCommutativeVal>,
4616        #[wavl_node]
4617        node: WavlTreeNode<TestNonCommutativeObject>,
4618    }
4619
4620    impl TestNonCommutativeObject {
4621        fn new(value: i32) -> Self {
4622            Self {
4623                value,
4624                subtree_val: core::cell::Cell::new(NonCommutativeVal::default()),
4625                node: WavlTreeNode::new(),
4626            }
4627        }
4628    }
4629
4630    impl WavlTreeKeyable<i32> for TestNonCommutativeObject {
4631        type Key<'a> = i32;
4632        fn get_key(&self) -> i32 {
4633            self.value
4634        }
4635    }
4636
4637    struct NonCommutativeTraits;
4638    impl WavlTreeAugmentedInvariantObserverTraits for NonCommutativeTraits {
4639        type Target = TestNonCommutativeObject;
4640        type Value = NonCommutativeVal;
4641
4642        fn get_node_value(node: &Self::Target) -> Self::Value {
4643            NonCommutativeVal::single(node.value)
4644        }
4645
4646        fn get_subtree_value(node: &Self::Target) -> Self::Value {
4647            node.subtree_val.get()
4648        }
4649
4650        fn combine_values(a: Self::Value, b: Self::Value) -> Self::Value {
4651            NonCommutativeVal::combine(a, b)
4652        }
4653
4654        fn set_subtree_value(node: &Self::Target, val: Self::Value) {
4655            node.subtree_val.set(val);
4656        }
4657
4658        fn reset_subtree_value(node: &Self::Target) {
4659            node.subtree_val.set(NonCommutativeVal::default());
4660        }
4661    }
4662
4663    #[test]
4664    fn test_augmented_invariant_observer_non_commutative() {
4665        type TestObserver =
4666            WavlTreeAugmentedInvariantObserver<DefaultObjectTag, NonCommutativeTraits>;
4667        type TestTree = WavlTree<
4668            i32,
4669            UniquePtr<TestNonCommutativeObject>,
4670            DefaultObjectTag,
4671            TrackingSize,
4672            TestObserver,
4673        >;
4674
4675        stack_pin_init!(let tree = TestTree::new_with_observer(TestObserver::default()));
4676        let tree = unsafe { tree.get_unchecked_mut() };
4677
4678        // Helper to verify non-commutative subtree values recursively
4679        fn verify_subtree_values(node: *mut TestNonCommutativeObject) -> NonCommutativeVal {
4680            if !valid_sentinel_ptr(node) {
4681                return NonCommutativeVal::default();
4682            }
4683            let node_ref = unsafe { &*node };
4684            let ns = node_ref.get_node();
4685            let left_val = verify_subtree_values(ns.get_left());
4686            let node_val = NonCommutativeVal::single(node_ref.value);
4687            let right_val = verify_subtree_values(ns.get_right());
4688            let expected = NonCommutativeVal::combine(
4689                NonCommutativeVal::combine(left_val, node_val),
4690                right_val,
4691            );
4692            assert_eq!(
4693                node_ref.subtree_val.get(),
4694                expected,
4695                "Subtree non-commutative value mismatch at node {}",
4696                node_ref.value
4697            );
4698            expected
4699        }
4700
4701        // Helper to compute expected in-order value from a list of sorted keys
4702        fn expected_in_order(keys: &[i32]) -> NonCommutativeVal {
4703            let mut sorted: alloc::vec::Vec<i32> = keys.iter().copied().collect();
4704            sorted.sort();
4705            let mut acc = NonCommutativeVal::default();
4706            for &k in &sorted {
4707                acc = NonCommutativeVal::combine(acc, NonCommutativeVal::single(k));
4708            }
4709            acc
4710        }
4711
4712        // Insert nodes in an order that triggers single and double rotations in both directions
4713        let values = [10, 20, 5, 15, 25, 2, 7, 1, 3, 6, 8, 12, 17, 22, 30];
4714        for (i, &val) in values.iter().enumerate() {
4715            let obj = UniquePtr::try_new(TestNonCommutativeObject::new(val)).unwrap();
4716            tree.insert(obj);
4717            if !tree.root.is_null() {
4718                verify_subtree_values(tree.root);
4719                let expected = expected_in_order(&values[..=i]);
4720                assert_eq!(unsafe { &*tree.root }.subtree_val.get(), expected);
4721            }
4722        }
4723
4724        // Erase nodes causing rebalancings/rotations
4725        let to_erase = [5, 20, 15, 2, 25];
4726        let mut remaining: alloc::vec::Vec<i32> = values.iter().copied().collect();
4727        for &val in &to_erase {
4728            let erased = tree.erase(&val);
4729            assert!(erased.is_some());
4730            assert_eq!(erased.as_ref().unwrap().value, val);
4731            remaining.retain(|&x| x != val);
4732            if !tree.root.is_null() {
4733                verify_subtree_values(tree.root);
4734                let expected = expected_in_order(&remaining);
4735                assert_eq!(unsafe { &*tree.root }.subtree_val.get(), expected);
4736            }
4737        }
4738    }
4739
4740    #[test]
4741    fn test_successor_raw() {
4742        type TestTree = WavlTree<i32, *mut TestObject>;
4743        stack_pin_init!(let tree = TestTree::new());
4744        let tree = unsafe { tree.get_unchecked_mut() };
4745
4746        let mut cur: *mut TestObject = core::ptr::null_mut();
4747        unsafe { TestTree::successor_raw(&mut cur) };
4748        assert!(cur.is_null());
4749
4750        let mut cur = tree.front_cursor().as_raw_ptr();
4751        assert!(is_sentinel_ptr(cur));
4752        unsafe { TestTree::successor_raw(&mut cur) };
4753        assert!(cur.is_null());
4754
4755        let mut objs =
4756            [TestObject::new(20), TestObject::new(10), TestObject::new(30), TestObject::new(15)];
4757        for obj in &mut objs {
4758            unsafe { tree.insert_raw(obj) };
4759        }
4760
4761        let mut visited = alloc::vec::Vec::new();
4762        let mut cur = tree.front_cursor().as_raw_ptr();
4763        while !cur.is_null() {
4764            visited.push(unsafe { (*cur).value });
4765            unsafe { TestTree::successor_raw(&mut cur) };
4766        }
4767        assert_eq!(visited, alloc::vec![10, 15, 20, 30]);
4768
4769        for obj in &mut objs {
4770            unsafe { tree.erase_raw(obj) };
4771        }
4772    }
4773}