Next Generation WASM Microkernel Operating System
1// Copyright 2025 Jonas Kruckenberg
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! # An intrusive Weak AVL Tree.
9//!
10//! A Rust implementation of Weak AVL Trees, primarily for use in the [k23 operating system][k23].
11//!
12//! Weak AVL trees are *self-balancing binary search trees* introduced by [Haeupler, Sen & Tarjan (2015)][paper] that are
13//! similar to red-black trees but better in several ways.
14//! In particular, their worst-case height is that of AVL trees (~1.44log2(n) as opposed to 2log2(n) for red-black trees),
15//! while tree restructuring operations after deletions are even more efficient than red-black trees.
16//! Additionally, this implementation is *intrusive* meaning node data (pointers to other nodes etc.) are stored _within_
17//! participating values, rather than being allocated and owned by the tree itself.
18//!
19//! **This crate is self-contained, (somewhat) fuzzed, and fully `no_std`.**
20//!
21//! ## Example
22//!
23//! The following example shows an implementation of a simple intrusive WAVL tree node (`MyNode`) and
24//! how it can be used with `WAVLTree`, notice how - due to the intrusive nature of the data structure -
25//! there is quite a lot more setup required, compared to e.g. a `BTreeMap` or `HashMap`.
26//!
27//! ```rust
28//! # extern crate alloc;
29//! # use alloc::boxed::Box;
30//! # use core::mem::offset_of;
31//! # use core::pin::Pin;
32//! # use core::ptr::NonNull;
33//! #[derive(Default)]
34//! struct MyNode {
35//! links: wavltree::Links<Self>,
36//! value: usize,
37//! }
38//!
39//! impl MyNode {
40//! pub fn new(value: usize) -> Self {
41//! let mut this = Self::default();
42//! this.value = value;
43//! this
44//! }
45//! }
46//!
47//! // Participation in an intrusive collection requires a bit more effort
48//! // on the values's part.
49//! unsafe impl wavltree::Linked for MyNode {
50//! /// The owning handle type, must ensure participating values are pinned in memory.
51//! type Handle = Pin<Box<Self>>;
52//! /// The key type by which entries are identified.
53//! type Key = usize;
54//!
55//! /// Convert a `Handle` into a raw pointer to `Self`,
56//! /// taking ownership of it in the process.
57//! fn into_ptr(handle: Self::Handle) -> NonNull<Self> {
58//! unsafe { NonNull::from(Box::leak(Pin::into_inner_unchecked(handle))) }
59//! }
60//!
61//! /// Convert a raw pointer back into an owned `Handle`.
62//! unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle {
63//! Pin::new_unchecked(Box::from_raw(ptr.as_ptr()))
64//! }
65//!
66//! /// Return the links of the node pointed to by ptr.
67//! unsafe fn links(ptr: NonNull<Self>) -> NonNull<wavltree::Links<Self>> {
68//! ptr.map_addr(|addr| {
69//! let offset = offset_of!(Self, links);
70//! addr.checked_add(offset).unwrap()
71//! })
72//! .cast()
73//! }
74//!
75//! /// Retrieve the key identifying this node within the collection.
76//! fn get_key(&self) -> &Self::Key {
77//! &self.value
78//! }
79//! }
80//!
81//! fn main() {
82//! let mut tree = wavltree::WAVLTree::new();
83//! tree.insert(Box::pin(MyNode::new(42)));
84//! tree.insert(Box::pin(MyNode::new(17)));
85//! tree.insert(Box::pin(MyNode::new(9)));
86//!
87//! tree.remove(&9);
88//!
89//! let _entry = tree.entry(&42);
90//! }
91//! ```
92//!
93//! ## When To Use This
94//!
95//! - **want binary search** - WAVL trees are *sorted* collections that are efficient to search.
96//! - **search more than you edit** - WAVL trees offer better search complexity than red-black trees at the cost of being
97//! slightly more complex.
98//! - **want to avoid hidden allocations** - Because node data is stored _inside_ participating values, an element can be
99//! added without requiring additional heap allocations.
100//! - **have to allocator at all** - When elements have fixed memory locations (such as pages in a page allocator, `static`s),
101//! they can be added without *any allocations at all*.
102//! - **want flexibility** - Intrusive data structures allow elements to participate in many different collections at the
103//! same time, e.g. a node might both be linked to a `WAVLTree` and an intrusive doubly-linked list at the same time.
104//!
105//! In short, `WAVLTree`s are a good choice for `no_std` binary search trees such as inside page allocators.
106//!
107//! ## When Not To Use This
108//!
109//! - **need to store primitives** - Intrusive collections require elements to store the node data, which excludes
110//! primitives such as strings or numbers, since they can't hold this metadata.
111//! - **can't use unsafe** - Both this implementation and code consuming it require `unsafe`, the `Linked` trait is unsafe
112//! to implement since it requires implementors uphold special invariants.
113//! - **you are unsure if you need this** - Search trees and especially intrusive ones like this are niche data structures,
114//! only use them if you are sure you need them. Very likely doing binary search on a sorted `Vec` or using a `HashMap`
115//! works better for your use case.
116//!
117//! ## Cargo Features
118//!
119//! The following features are available:
120//!
121//! | Feature | Default | Explanation |
122//! |:--------|:--------|:------------------------------------------------------------------------------------------|
123//! | `dot` | `false` | Enables the `WAVLTree::dot` method, which allows display of the tree in [graphviz format] |
124//!
125//! [paper]: https://sidsen.azurewebsites.net/papers/rb-trees-talg.pdf
126//! [k23]: https://github.com/JonasKruckenberg/k23
127//! [graphviz format]: https://graphviz.org
128
129#![cfg_attr(not(test), no_std)]
130#![feature(let_chains)]
131#![allow(
132 clippy::undocumented_unsafe_blocks,
133 reason = "too many trivial unsafe blocks"
134)]
135
136mod cursor;
137#[cfg(feature = "dot")]
138mod dot;
139mod entry;
140mod iter;
141mod utils;
142
143use core::borrow::Borrow;
144use core::cell::UnsafeCell;
145use core::cmp::Ordering;
146use core::marker::PhantomPinned;
147use core::ops::{Bound, RangeBounds};
148use core::pin::Pin;
149use core::ptr::NonNull;
150use core::{fmt, mem, ptr};
151
152pub use crate::cursor::{Cursor, CursorMut};
153pub use crate::entry::{Entry, OccupiedEntry, VacantEntry};
154use crate::utils::get_sibling;
155#[cfg(feature = "dot")]
156pub use dot::Dot;
157pub use iter::IntoIter;
158pub use iter::{Iter, IterMut};
159pub use utils::Side;
160
161/// Trait implemented by types which can be members of an [intrusive WAVL tree][WAVLTree].
162///
163/// In order to be part of an intrusive WAVL tree, a type must contain a
164/// `Links` type that stores the pointers to other nodes in the tree.
165///
166/// # Safety
167///
168/// This is unsafe to implement because it's the implementation's responsibility
169/// to ensure that types implementing this trait are valid intrusive collection
170/// nodes. In particular:
171///
172/// - Implementations **must** ensure that implementors are pinned in memory while they
173/// are in an intrusive collection. While a given `Linked` type is in an intrusive
174/// data structure, it may not be deallocated or moved to a different memory
175/// location.
176/// - The type implementing this trait **must not** implement [`Unpin`].
177/// - Additional safety requirements for individual methods on this trait are
178/// documented on those methods.
179///
180/// Failure to uphold these invariants will result in corruption of the
181/// intrusive data structure, including dangling pointers.
182///
183/// # Implementing `Linked::links`
184///
185/// The [`Linked::links`] method provides access to a `Linked` type's `Links`
186/// field through a [`NonNull`] pointer. This is necessary for a type to
187/// participate in an intrusive structure, as it tells the intrusive structure
188/// how to access the links to other parts of that data structure. However, this
189/// method is somewhat difficult to implement correctly.
190///
191/// Suppose we have an element type like this:
192/// ```rust
193/// struct Entry {
194/// links: wavltree::Links<Self>,
195/// data: usize,
196/// }
197/// ```
198///
199/// The naive implementation of [`links`](Linked::links) for this `Entry` type
200/// might look like this:
201///
202/// ```
203/// use wavltree::Linked;
204/// use core::ptr::NonNull;
205///
206/// # struct Entry {
207/// # links: wavltree::Links<Self>,
208/// # data: usize
209/// # }
210///
211/// unsafe impl Linked for Entry {
212/// # type Handle = NonNull<Self>;
213/// # type Key = usize;
214/// # fn get_key(&self) -> &Self::Key { &self.data }
215/// # fn into_ptr(r: Self::Handle) -> NonNull<Self> { r }
216/// # unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle { ptr }
217/// // ...
218///
219/// unsafe fn links(mut target: NonNull<Self>) -> NonNull<wavltree::Links<Self>> {
220/// // Borrow the target's `links` field.
221/// let links = &mut target.as_mut().links;
222/// // Convert that reference into a pointer.
223/// NonNull::from(links)
224/// }
225/// }
226/// ```
227///
228/// However, this implementation **is not sound** under [Stacked Borrows]! It
229/// creates a temporary reference from the original raw pointer, and then
230/// creates a new raw pointer from that temporary reference. Stacked Borrows
231/// will reject this reborrow as unsound.[^1]
232///
233/// There are two ways we can implement [`Linked::links`] without creating a
234/// temporary reference in this manner. The recommended one is to use the
235/// [`ptr::addr_of_mut!`] macro, as follows:
236///
237/// ```
238/// use core::ptr::{self, NonNull};
239/// # use wavltree::Linked;
240/// # struct Entry {
241/// # links: wavltree::Links<Self>,
242/// # data: usize,
243/// # }
244///
245/// unsafe impl Linked for Entry {
246/// # type Handle = NonNull<Self>;
247/// # type Key = usize;
248/// # fn get_key(&self) -> &Self::Key { &self.data }
249/// # fn into_ptr(r: Self::Handle) -> NonNull<Self> { r }
250/// # unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle { ptr }
251/// // ...
252///
253/// unsafe fn links(target: NonNull<Self>) -> NonNull<wavltree::Links<Self>> {
254/// // Note that we use the `map_addr` method here that is part of the strict-provenance
255/// target
256/// .map_addr(|addr| {
257/// // Using the `offset_of!` macro here to calculate the offset of the `links` field
258/// // in our overall struct.
259/// let offset = core::mem::offset_of!(Self, links);
260/// addr.checked_add(offset).unwrap()
261/// })
262/// .cast()
263/// }
264/// }
265/// ```
266///
267/// [^1]: Note that code like this is not *currently* known to result in
268/// miscompiles, but it is rejected by tools like Miri as being unsound.
269/// Like all undefined behavior, there is no guarantee that future Rust
270/// compilers will not miscompile code like this, with disastrous results.
271///
272/// [^2]: And two different fields cannot both be the first field at the same
273/// time...by definition.
274///
275/// [intrusive collection]: crate#intrusive-data-structures
276/// [`Unpin`]: Unpin
277/// [Stacked Borrows]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md
278pub unsafe trait Linked {
279 /// The handle owning nodes in the tree.
280 ///
281 /// This type must have ownership over a `Self`-typed value. When a `Handle`
282 /// is dropped, it should drop the corresponding `Linked` type.
283 ///
284 /// A quintessential example of a `Handle` is `Box`.
285 type Handle;
286
287 /// The type by which entries are identified.
288 ///
289 /// This type must be a unique identifier of an element, as it is used as the key for all public facing methods (e.g. `[WAVLTree::find`]).
290 ///
291 /// WAVL trees are sorted meaning that elements must form a total order (entries must be comparable
292 /// using `<` and `>`). However, placing the `Ord` requirement directly on entries makes for an
293 /// awkward API thanks to the intrusive nature of the data structure, so consumers may define a
294 /// custom key type (and key extraction method [`Linked::get_key`]) by which entries are compared.
295 ///
296 /// # Example
297 ///
298 /// Suppose this is our element data structure where we want to identify entries *only* by their age.
299 ///
300 /// ```rust
301 /// struct Entry {
302 /// links: wavltree::Links<Self>,
303 /// age: u16,
304 /// name: String
305 /// }
306 ///
307 /// ```
308 ///
309 /// The corresponding `Linked` implementation would look like this:
310 ///
311 /// ```rust
312 /// # use std::ptr::NonNull;
313 ///
314 /// # struct Entry {
315 /// # links: wavltree::Links<Self>,
316 /// # age: u16,
317 /// # name: String
318 /// # }
319 ///
320 /// unsafe impl wavltree::Linked for Entry {
321 /// # type Handle = NonNull<Self>;
322 /// # fn into_ptr(r: Self::Handle) -> NonNull<Self> { r }
323 /// # unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle { ptr }
324 /// # unsafe fn links(ptr: NonNull<Self>) -> NonNull<wavltree::Links<Entry>> { ptr.map_addr(|a| {
325 /// # a.checked_add(core::mem::offset_of!(Self, links)).unwrap()
326 /// # }).cast() }
327 /// // ...
328 ///
329 /// /// The age is our key
330 /// type Key = u16;
331 ///
332 /// /// We just need to retrieve the age from self
333 /// fn get_key(&self) -> &Self::Key {
334 /// &self.age
335 /// }
336 /// }
337 /// ```
338 type Key: Ord;
339
340 // Required methods
341 /// Convert a [`Self::Handle`] to a raw pointer to `Self`, taking ownership
342 /// of it in the process.
343 fn into_ptr(r: Self::Handle) -> NonNull<Self>;
344 /// Convert a raw pointer to Self into an owning Self::Handle.
345 ///
346 /// # Safety
347 /// This function is safe to call when:
348 ///
349 /// It is valid to construct a Self::Handle from a`raw pointer
350 /// The pointer points to a valid instance of Self (e.g. it does not dangle).
351 unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle;
352 /// Return the links of the node pointed to by ptr.
353 ///
354 /// # Safety
355 /// This function is safe to call when:
356 ///
357 /// It is valid to construct a Self::Handle from a`raw pointer
358 /// The pointer points to a valid instance of Self (e.g. it does not dangle).
359 /// See the [the trait-level documentation](#implementing-linkedlinks) documentation for details on how to correctly implement this method.
360 unsafe fn links(ptr: NonNull<Self>) -> NonNull<Links<Self>>;
361
362 /// Retrieve the key identifying this node within the collection. See [`Linked::Key`] for details.
363 fn get_key(&self) -> &Self::Key;
364
365 /// Invoked on the pivot node, its parent, children, and sibling before a
366 /// rotation, just before updating the pointers in the relevant nodes.
367 /// The direction of rotation is given by `side`.
368 ///
369 /// The following diagrams the relationship of the nodes in a left rotation (right rotations are
370 /// mirrored):
371 ///
372 /// ```text
373 /// parent self
374 /// / \ / \
375 /// sibling self -------> parent rl_child
376 /// / \ / \
377 /// lr_child rl_child sibling lr_child
378 /// ```
379 ///
380 /// Note that this hook will be called during double rotations too, once for the opposite side subtree
381 /// rotation and once for the final rotation.
382 #[allow(unused, reason = "trait declaration")]
383 fn after_rotate(
384 self: Pin<&mut Self>,
385 parent: NonNull<Self>,
386 sibling: Link<Self>,
387 lr_child: Link<Self>,
388 side: Side,
389 ) {
390 }
391
392 /// Invoked on the node to be erased and the node in the tree where the
393 /// augmented invariants become invalid, leading up to the root. Called just
394 /// after updating the pointers in the relevant nodes, but before rebalancing.
395 #[allow(unused, reason = "trait declaration")]
396 fn after_remove(self: Pin<&mut Self>, parent: Link<Self>) {}
397
398 /// Invoked on the newly inserted node before rebalancing.
399 fn after_insert(self: Pin<&mut Self>) {}
400}
401
402type Link<T> = Option<NonNull<T>>;
403
404/// An intrusive Weak AVL Tree.
405///
406/// This data structure supports efficient O(log n) lookup of elements and may be used for binary search.
407/// All operations complete in logarithmic time.
408///
409/// A weak AVL Tree (also called WAVL tree) is binary search tree closely related
410/// to AVL trees and red-black trees, combining the best properties of both.
411/// When built using insertions only it has the same upper height bound of AVL trees (~1.44 log2(n)
412/// where n is the number of elements in the tree) while at the same time requiring only a constant
413/// number of rotations for insertions and deletions (worst case deletion requires 2 rotations).
414pub struct WAVLTree<T>
415where
416 T: Linked + ?Sized,
417{
418 pub(crate) root: Link<T>,
419 size: usize,
420}
421
422unsafe impl<T> Send for WAVLTree<T> where T: Linked + ?Sized {}
423unsafe impl<T> Sync for WAVLTree<T> where T: Linked + ?Sized {}
424
425impl<T> Drop for WAVLTree<T>
426where
427 T: Linked + ?Sized,
428{
429 fn drop(&mut self) {
430 self.clear();
431 }
432}
433
434impl<T> Default for WAVLTree<T>
435where
436 T: Linked + ?Sized,
437{
438 fn default() -> Self {
439 Self::new()
440 }
441}
442
443impl<T> IntoIterator for WAVLTree<T>
444where
445 T: Linked + ?Sized,
446{
447 type Item = T::Handle;
448 type IntoIter = IntoIter<T>;
449
450 fn into_iter(self) -> Self::IntoIter {
451 #[allow(if_let_rescope, reason = "")]
452 if let Some(root) = self.root {
453 IntoIter {
454 // TODO this could be optimized by caching the head and tail nodes in the WAVLTree
455 head: Some(utils::find_minimum(root)),
456 tail: Some(utils::find_maximum(root)),
457 _tree: self,
458 }
459 } else {
460 IntoIter {
461 head: None,
462 tail: None,
463 _tree: self,
464 }
465 }
466 }
467}
468
469impl<T> WAVLTree<T>
470where
471 T: Linked + ?Sized,
472{
473 /// Creates a new, empty tree.
474 #[must_use]
475 pub const fn new() -> Self {
476 Self {
477 root: None,
478 size: 0,
479 }
480 }
481
482 /// Returns the number of entries in the tree.
483 pub fn size(&self) -> usize {
484 self.size
485 }
486
487 /// Returns `true` if the tree contains no entries.
488 pub fn is_empty(&self) -> bool {
489 debug_assert_eq!(self.root.is_none(), self.size() == 0);
490 self.size() == 0
491 }
492
493 /// Returns a double-ended iterator over a sub-range of entries in the tree. The simplest way is
494 /// to use the range syntax `min..max`, thus `range(min..max)` will yield elements from min (inclusive)
495 /// to max (exclusive). The range may also be entered as `(Bound<T>, Bound<T>)`, so for example
496 /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
497 /// range from 4 to 10.
498 pub fn range<Q, R>(&self, range: R) -> Iter<'_, T>
499 where
500 <T as Linked>::Key: Borrow<Q>,
501 Q: Ord,
502 R: RangeBounds<Q>,
503 {
504 if self.is_empty() {
505 return Iter {
506 head: None,
507 tail: None,
508 _tree: self,
509 };
510 }
511
512 let start = self.find_lower_bound(range.start_bound());
513 let end = self.find_upper_bound(range.end_bound());
514
515 Iter {
516 head: start,
517 tail: end,
518 _tree: self,
519 }
520 }
521
522 /// Returns a mutable double-ended iterator over a sub-range of entries in the tree. The simplest way is
523 /// to use the range syntax `min..max`, thus `range(min..max)` will yield elements from min (inclusive)
524 /// to max (exclusive). The range may also be entered as `(Bound<T>, Bound<T>)`, so for example
525 /// `range((Excluded(4), Included(10)))` will yield a left-exclusive, right-inclusive
526 /// range from 4 to 10.
527 pub fn range_mut<Q, R>(&mut self, range: R) -> IterMut<'_, T>
528 where
529 <T as Linked>::Key: Borrow<Q>,
530 Q: Ord,
531 R: RangeBounds<Q>,
532 {
533 if self.is_empty() {
534 return IterMut {
535 head: None,
536 tail: None,
537 _tree: self,
538 };
539 }
540
541 let head = self.find_lower_bound(range.start_bound());
542 let tail = self.find_upper_bound(range.end_bound());
543
544 IterMut {
545 head: head.or(tail),
546 tail,
547 _tree: self,
548 }
549 }
550
551 /// Returns the given key's corresponding entry in the tree for in-place manipulation.
552 pub fn entry<Q>(&mut self, key: &Q) -> Entry<'_, T>
553 where
554 <T as Linked>::Key: Borrow<Q>,
555 Q: Ord,
556 {
557 let (node, parent_and_side) = self.find_internal(key);
558
559 if let Some(node) = node {
560 Entry::Occupied(OccupiedEntry { node, _tree: self })
561 } else {
562 Entry::Vacant(VacantEntry {
563 parent_and_side,
564 _tree: self,
565 })
566 }
567 }
568
569 pub fn find<Q>(&self, key: &Q) -> Cursor<'_, T>
570 where
571 <T as Linked>::Key: Borrow<Q>,
572 Q: Ord,
573 {
574 let (current, _) = self.find_internal(key);
575 Cursor {
576 current,
577 _tree: self,
578 }
579 }
580
581 pub fn find_mut<Q>(&mut self, key: &Q) -> CursorMut<'_, T>
582 where
583 <T as Linked>::Key: Borrow<Q>,
584 Q: Ord,
585 {
586 let (current, _) = self.find_internal(key);
587 CursorMut {
588 current,
589 _tree: self,
590 }
591 }
592
593 /// Returns a cursor to the root of the tree.
594 #[inline]
595 pub fn root(&self) -> Cursor<'_, T> {
596 Cursor {
597 current: self.root,
598 _tree: self,
599 }
600 }
601
602 /// Returns a mutable cursor to the root of the tree.
603 #[inline]
604 pub fn root_mut(&mut self) -> CursorMut<'_, T> {
605 CursorMut {
606 current: self.root,
607 _tree: self,
608 }
609 }
610
611 /// Returns a cursor to the first element of the tree.
612 #[inline]
613 pub fn front(&self) -> Cursor<'_, T> {
614 Cursor {
615 current: self.root.map(|root| utils::find_minimum(root)),
616 _tree: self,
617 }
618 }
619
620 /// Returns a mutable cursor to the first element of the tree.
621 #[inline]
622 pub fn front_mut(&mut self) -> CursorMut<'_, T> {
623 CursorMut {
624 current: self.root.map(|root| utils::find_minimum(root)),
625 _tree: self,
626 }
627 }
628
629 /// Returns a cursor to the last element of the tree.
630 #[inline]
631 pub fn back(&self) -> Cursor<'_, T> {
632 Cursor {
633 current: self.root.map(|root| utils::find_maximum(root)),
634 _tree: self,
635 }
636 }
637
638 /// Returns a mutable cursor to the last element of the tree.
639 #[inline]
640 pub fn back_mut(&mut self) -> CursorMut<'_, T> {
641 CursorMut {
642 current: self.root.map(|root| utils::find_maximum(root)),
643 _tree: self,
644 }
645 }
646
647 /// Constructs a cursor from a raw pointer to a node.
648 ///
649 /// # Safety
650 ///
651 /// Caller has to ensure the pointer points to a valid node in the tree.
652 #[inline]
653 pub unsafe fn cursor_from_ptr(&self, ptr: NonNull<T>) -> Cursor<'_, T> {
654 debug_assert!(unsafe { T::links(ptr).as_ref() }.is_linked());
655 Cursor {
656 current: Some(ptr),
657 _tree: self,
658 }
659 }
660
661 /// Constructs a mutable cursor from a raw pointer to a node.
662 ///
663 /// # Safety
664 ///
665 /// Caller has to ensure the pointer points to a valid node in the tree.
666 #[inline]
667 pub unsafe fn cursor_mut_from_ptr(&mut self, ptr: NonNull<T>) -> CursorMut<'_, T> {
668 debug_assert!(
669 unsafe { T::links(ptr).as_ref() }.is_linked(),
670 "ptr {ptr:?} is not a linked element"
671 );
672 CursorMut {
673 current: Some(ptr),
674 _tree: self,
675 }
676 }
677
678 /// Insert a new entry into the `WAVLTree`.
679 ///
680 /// # Panics
681 ///
682 /// Panics if the new entry is already linked to a different intrusive collection.
683 pub fn insert(&mut self, element: T::Handle) -> Pin<&mut T> {
684 unsafe {
685 let mut ptr = T::into_ptr(element);
686 debug_assert_ne!(self.root, Some(ptr));
687
688 let ptr_links = T::links(ptr).as_mut();
689 assert!(!ptr_links.is_linked());
690
691 let key = T::get_key(ptr.as_ref());
692
693 let was_leaf = if let Some(mut curr) = self.root {
694 loop {
695 let curr_links = T::links(curr).as_mut();
696
697 let side = match key.cmp(curr.as_ref().get_key().borrow()) {
698 Ordering::Equal => panic!("already inserted"),
699 Ordering::Less => Side::Left,
700 Ordering::Greater => Side::Right,
701 };
702
703 if let Some(child) = curr_links.child(side) {
704 curr = child;
705 } else {
706 let was_leaf = curr_links.is_leaf();
707 ptr_links.replace_parent(Some(curr));
708 curr_links.replace_child(side, Some(ptr));
709 break was_leaf;
710 }
711 }
712 } else {
713 self.root = Some(ptr);
714 false
715 };
716
717 T::after_insert(Pin::new_unchecked(ptr.as_mut()));
718 self.size += 1;
719
720 if was_leaf {
721 self.balance_after_insert(ptr);
722 }
723
724 Pin::new_unchecked(ptr.as_mut())
725 }
726 }
727
728 /// Removes an entry - identified by the given key - from the tree, returning the owned handle
729 /// if the associated entry was part of the tree.
730 ///
731 /// The key may be any borrowed form of the entry’s key type, but the ordering on the borrowed
732 /// form *must* match the ordering on the key type.
733 pub fn remove<Q>(&mut self, key: &Q) -> Option<T::Handle>
734 where
735 <T as Linked>::Key: Borrow<Q>,
736 Q: Ord,
737 {
738 let ptr = self.find_internal(key).0?;
739 self.size -= 1;
740 Some(self.remove_internal(ptr))
741 }
742
743 /// Returns a [`Cursor`] pointing at the gap before the smallest key greater than the given bound.
744 #[inline]
745 pub fn lower_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, T>
746 where
747 <T as Linked>::Key: Borrow<Q>,
748 Q: Ord,
749 {
750 Cursor {
751 current: self.find_lower_bound(bound),
752 _tree: self,
753 }
754 }
755
756 /// Returns a [`CursorMut`] pointing at the gap before the smallest key greater than the given bound.
757 #[inline]
758 pub fn lower_bound_mut<Q>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T>
759 where
760 <T as Linked>::Key: Borrow<Q>,
761 Q: Ord,
762 {
763 CursorMut {
764 current: self.find_lower_bound(bound),
765 _tree: self,
766 }
767 }
768
769 /// Returns a [`Cursor`] pointing at the gap after the greatest key smaller than the given bound.
770 #[inline]
771 pub fn upper_bound<Q>(&self, bound: Bound<&Q>) -> Cursor<'_, T>
772 where
773 <T as Linked>::Key: Borrow<Q>,
774 Q: Ord,
775 {
776 Cursor {
777 current: self.find_upper_bound(bound),
778 _tree: self,
779 }
780 }
781
782 /// Returns a [`CursorMut`] pointing at the gap after the greatest key smaller than the given bound.
783 #[inline]
784 pub fn upper_bound_mut<Q>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T>
785 where
786 <T as Linked>::Key: Borrow<Q>,
787 Q: Ord,
788 {
789 CursorMut {
790 current: self.find_upper_bound(bound),
791 _tree: self,
792 }
793 }
794
795 /// Gets an iterator over the entries in the tree, sorted by their key.
796 pub fn iter(&self) -> Iter<'_, T> {
797 Iter {
798 head: self.root.map(|root| utils::find_minimum(root)),
799 tail: self.root.map(|root| utils::find_maximum(root)),
800 _tree: self,
801 }
802 }
803
804 /// Gets a mutable iterator over the entries in the tree, sorted by their key.
805 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
806 IterMut {
807 head: self.root.map(|root| utils::find_minimum(root)),
808 tail: self.root.map(|root| utils::find_maximum(root)),
809 _tree: self,
810 }
811 }
812
813 /// Removes all elements from the tree.
814 ///
815 /// This will properly unlink and drop all entries, which requires iterating through the tree.
816 pub fn clear(&mut self) {
817 if let Some(root) = self.root.take() {
818 self.clear_inner(root);
819 }
820 }
821
822 #[inline]
823 #[allow(
824 clippy::only_used_in_recursion,
825 reason = "need to ensure tree is borrowed for the entire time we operate on it"
826 )]
827 fn clear_inner(&mut self, node: NonNull<T>) {
828 unsafe {
829 let node_links = T::links(node).as_mut();
830 if let Some(left) = node_links.left() {
831 self.clear_inner(left);
832 }
833 if let Some(right) = node_links.right() {
834 self.clear_inner(right);
835 }
836 node_links.unlink();
837 T::from_ptr(node);
838 }
839 }
840
841 /// Takes all the elements out of the `WAVLTree`, leaving it empty. The taken elements are returned as a new `WAVLTree`.
842 #[inline]
843 pub fn take(&mut self) -> Self {
844 let tree = Self {
845 root: self.root,
846 size: self.size,
847 };
848 self.root = None;
849 tree
850 }
851
852 /// Asserts as many of the tree's invariants as possible.
853 ///
854 /// Note that with debug assertions enabled, this includes validating the WAVL rank-balancing
855 /// rules **which is disabled otherwise**.
856 #[track_caller]
857 pub fn assert_valid(&self) {
858 unsafe {
859 if let Some(root) = self.root {
860 let root_links = T::links(root).as_ref();
861 root_links.assert_valid();
862
863 if let Some(left) = root_links.left() {
864 Self::assert_valid_inner(left, root);
865 }
866
867 if let Some(right) = root_links.right() {
868 Self::assert_valid_inner(right, root);
869 }
870 }
871 }
872 }
873
874 #[track_caller]
875 #[cfg_attr(not(debug_assertions), allow(unused))]
876 fn assert_valid_inner(node: NonNull<T>, parent: NonNull<T>) {
877 unsafe {
878 let node_links = T::links(node).as_ref();
879
880 // assert that all links are set up correctly (no loops, self references, etc.)
881 node_links.assert_valid();
882
883 // We can only check the WAVL rule if we track the rank, which we only do in debug builds
884 #[cfg(debug_assertions)]
885 {
886 let parent_links = T::links(parent).as_ref();
887
888 // Weak AVL Rule: All rank differences are 1 or 2 and every leaf has rank 0.
889 let rank_diff = parent_links.rank() - node_links.rank();
890 assert!(
891 rank_diff <= 2 && rank_diff > 0,
892 "WAVL rank rule violation: rank difference must be 1 or 2, but was {rank_diff}; node = {node:#?}, parent = {parent:#?}",
893 );
894 if node_links.is_leaf() {
895 assert_eq!(
896 node_links.rank(),
897 0,
898 "WAVL rank rule violation: leaf must be rank 0, but was {}",
899 node_links.rank(),
900 );
901 }
902 }
903
904 if let Some(left) = node_links.left() {
905 // Assert that values in the right subtree are indeed less
906 assert!(
907 left.as_ref().get_key() < node.as_ref().get_key(),
908 "Ordering violation: left subtree is not less than node"
909 );
910 Self::assert_valid_inner(left, node);
911 }
912
913 if let Some(right) = node_links.right() {
914 // Assert that values in the right subtree are indeed greater
915 assert!(
916 right.as_ref().get_key() > node.as_ref().get_key(),
917 "Ordering violation: right subtree is not greater than node"
918 );
919 Self::assert_valid_inner(right, node);
920 }
921 }
922 }
923
924 #[cfg(feature = "dot")]
925 pub fn dot(&self) -> Dot<'_, T> {
926 Dot { tree: self }
927 }
928
929 fn find_lower_bound<Q>(&self, bound: Bound<&Q>) -> Option<NonNull<T>>
930 where
931 <T as Linked>::Key: Borrow<Q>,
932 Q: Ord,
933 {
934 let mut result = None;
935 let mut tree = self.root;
936 while let Some(curr) = tree {
937 let curr_lks = unsafe { T::links(curr).as_ref() };
938
939 let cond = match bound {
940 Bound::Included(key) => key <= unsafe { curr.as_ref() }.get_key().borrow(),
941 Bound::Excluded(key) => key < unsafe { curr.as_ref() }.get_key().borrow(),
942 Bound::Unbounded => true,
943 };
944
945 if cond {
946 result = tree;
947 tree = curr_lks.left();
948 } else {
949 tree = curr_lks.right();
950 }
951 }
952
953 result
954 }
955
956 fn find_upper_bound<Q>(&self, bound: Bound<&Q>) -> Option<NonNull<T>>
957 where
958 <T as Linked>::Key: Borrow<Q>,
959 Q: Ord,
960 {
961 let mut result = None;
962 let mut tree = self.root;
963 while let Some(curr) = tree {
964 let curr_lks = unsafe { T::links(curr).as_ref() };
965
966 let cond = match bound {
967 Bound::Included(key) => key < unsafe { curr.as_ref() }.get_key().borrow(),
968 Bound::Excluded(key) => key <= unsafe { curr.as_ref() }.get_key().borrow(),
969 Bound::Unbounded => false,
970 };
971
972 if cond {
973 tree = curr_lks.left();
974 } else {
975 result = tree;
976 tree = curr_lks.right();
977 }
978 }
979
980 result
981 }
982
983 #[expect(clippy::type_complexity, reason = "internal")]
984 fn find_internal<Q>(&self, key: &Q) -> (Option<NonNull<T>>, Option<(NonNull<T>, Side)>)
985 where
986 <T as Linked>::Key: Borrow<Q>,
987 Q: Ord,
988 {
989 let mut parent = None;
990 let mut tree = self.root;
991 while let Some(curr) = tree {
992 let curr_lks = unsafe { T::links(curr).as_ref() };
993
994 match key.cmp(unsafe { curr.as_ref() }.get_key().borrow()) {
995 Ordering::Equal => return (Some(curr), parent),
996 Ordering::Less => {
997 parent = Some((curr, Side::Left));
998 tree = curr_lks.left();
999 }
1000 Ordering::Greater => {
1001 parent = Some((curr, Side::Right));
1002 tree = curr_lks.right();
1003 }
1004 }
1005 }
1006
1007 (None, parent)
1008 }
1009
1010 fn remove_internal(&mut self, mut node: NonNull<T>) -> T::Handle {
1011 let node_links = unsafe { T::links(node).as_mut() };
1012 let parent = node_links.parent();
1013
1014 // Figure out which node we need to splice in, replacing node
1015 let y = if let Some(right) = node_links.right()
1016 && node_links.left().is_some()
1017 {
1018 utils::find_minimum(right)
1019 } else {
1020 node
1021 };
1022
1023 // Find the child if the node to that we will move up
1024 let y_links = unsafe { T::links(y).as_ref() };
1025 let mut p_y = y_links.parent();
1026 let x = y_links.left().or(y_links.right());
1027
1028 // Check if y is a 2-child of its parent
1029 let is_2_child = p_y.is_some_and(|parent| utils::node_is_2_child(y, parent));
1030
1031 // Replace Y with X which will effectively remove Y from the tree
1032 {
1033 if let Some(p_y) = y_links.parent() {
1034 let p_y_links = unsafe { T::links(p_y).as_mut() };
1035
1036 // Ensure the right/left pointer of the parent of the node to
1037 // be spliced out points to its new child
1038 if p_y_links.left() == Some(y) {
1039 p_y_links.replace_left(x);
1040 } else {
1041 assert_eq!(p_y_links.right(), Some(y));
1042 p_y_links.replace_right(x);
1043 }
1044 } else {
1045 // We're deleting the root, so swap in the new candidate
1046 self.root = x;
1047 }
1048
1049 // Splice in the child of the node to be removed
1050 if let Some(x) = x {
1051 unsafe { T::links(x).as_mut() }.replace_parent(y_links.parent());
1052 }
1053 }
1054
1055 if !ptr::eq(y.as_ptr(), node.as_ptr()) {
1056 self.swap_in_node_at(node, y);
1057 if p_y == Some(node) {
1058 p_y = Some(y);
1059 }
1060 }
1061
1062 T::after_remove(unsafe { Pin::new_unchecked(node.as_mut()) }, parent);
1063
1064 if let Some(p_y) = p_y {
1065 if is_2_child {
1066 self.rebalance_after_remove_3_child(x, p_y);
1067 } else if x.is_none() && unsafe { T::links(p_y).as_ref() }.is_leaf() {
1068 self.rebalance_after_remove_2_2_leaf(p_y);
1069 }
1070
1071 assert!(
1072 !(unsafe { T::links(p_y).as_ref() }.is_leaf()
1073 && unsafe { T::links(p_y).as_ref() }.rank_parity())
1074 );
1075 }
1076
1077 // unlink the node from the tree and return
1078 unsafe {
1079 node_links.unlink();
1080 T::from_ptr(node)
1081 }
1082 }
1083
1084 pub(crate) fn balance_after_insert(&mut self, mut x: NonNull<T>) {
1085 unsafe {
1086 let mut parent = T::links(x).as_ref().parent().unwrap();
1087
1088 // The WAVL rank rules require all rank differences to be either 1 or 2; 0 is now allowed.
1089 // The parent was previously a 1,1 leaf, but is now a 0,1 unary node. 0 is not allowed
1090 // so we need to rebalance.
1091 //
1092 // Sep 1: Promotion
1093 // We begin with promoting the parent nodes, according to the following algorithm:
1094 //
1095 // while parent_.is_some() && parent is 0,1
1096 // promote parent
1097 // move up the tree
1098 //
1099 // To determine whether parent is a 0,1 node, we need `curr`s rank parity,
1100 // `parent`s rank parity and the other sibling's parity which we read below.
1101 // Note, that they are all `let mut` because we need to update them each iteration.
1102
1103 let mut par_x: bool;
1104 let mut par_parent: bool;
1105 let mut par_sibling: bool;
1106 let mut sibling_side: Side;
1107
1108 loop {
1109 // promote
1110 let parent_links = T::links(parent).as_mut();
1111 parent_links.promote();
1112
1113 let Some(parent_) = parent_links.parent() else {
1114 return;
1115 };
1116
1117 // climb
1118 x = parent;
1119 parent = parent_;
1120
1121 // update parities
1122 // note that we explicitly create new `T::links` references here bc we just updated the pointers.
1123 par_x = T::links(x).as_ref().rank_parity();
1124 par_parent = T::links(parent).as_ref().rank_parity();
1125
1126 let (sibling, side) = utils::get_sibling(Some(x), parent);
1127 par_sibling = utils::get_link_parity(sibling);
1128 sibling_side = side;
1129
1130 // Let N, P and S denote the current node, parent, and sibling parities
1131 // that we read above. Then `parent` is 0,1 iff (!N * !P * S) + (N * P * !S)
1132 //
1133 // This means when the inverse is true, we reached a parent that's not 0,1 and so
1134 // we can stop the promotion loop.
1135 if (!par_x || !par_parent || par_sibling) && (par_x || par_parent || !par_sibling) {
1136 break;
1137 }
1138 }
1139
1140 // At this point we know `x` has a parent and that parent is not 0,1. So either,
1141 // the rank rule has been restored or the parent is 0,2.
1142 //
1143 // Using the notation above, our parent is 0,2 iff (!N * !P * !S) + (N * P * S).
1144 // The inverse can be expressed much more succinctly as (N != P) || (N != S)
1145 // (according to godbolt also generates 3x less code)
1146 //
1147 // Therefore, iff (N != P) || (N != S) the rank rule holds and we are done
1148 if (par_x != par_parent) || (par_x != par_sibling) {
1149 return;
1150 }
1151
1152 let x_links = T::links(x).as_mut();
1153 debug_assert!(x_links.parent().is_some());
1154
1155 // If X is a left child, we rotate right, if it's a right child we rotate left
1156 //
1157 // We define
1158 // - Y as X's child in direction of rotation
1159 // - Z as X's parent
1160 let y = x_links.child(sibling_side);
1161 let z = x_links.parent();
1162
1163 if let Some(y) = y
1164 && T::links(y).as_ref().rank_parity() != par_x
1165 {
1166 // If Y is a 1-child we do a double rotation, then demote x and z
1167 self.double_rotate_at(y, sibling_side);
1168
1169 T::links(y).as_mut().promote();
1170 x_links.demote();
1171 } else {
1172 // If not, do a single rotation and demote z
1173 self.rotate_at(x, sibling_side);
1174 }
1175
1176 // finish up by doing the z demotion
1177 if let Some(z) = z {
1178 T::links(z).as_mut().demote();
1179 }
1180 }
1181 }
1182
1183 fn rebalance_after_remove_3_child(&mut self, mut x: Link<T>, mut z: NonNull<T>) {
1184 let mut z_links = unsafe { T::links(z).as_mut() };
1185
1186 // Step 1: Demotions.
1187 //
1188 // The paper states "While X is 3-child and Y is a 2-child or 2,2"
1189 loop {
1190 let y = if z_links.left() == x {
1191 z_links.right()
1192 } else {
1193 z_links.left()
1194 };
1195
1196 let creates_3_node = z_links.parent().is_some_and(|p_z| {
1197 unsafe { T::links(p_z).as_ref() }.rank_parity() == z_links.rank_parity()
1198 });
1199
1200 if utils::get_link_parity(y) == z_links.rank_parity() {
1201 z_links.demote();
1202 } else {
1203 let y_links = unsafe { T::links(y.unwrap()).as_mut() };
1204
1205 // compute y_is_22_node
1206 let y_is_22_node = if y_links.rank_parity() {
1207 // If Y has odd rank parity, it is a 2,2 node if both its
1208 // children have odd parity, meaning each child either does
1209 // not exist, or exists and has odd parity.
1210 utils::get_link_parity(y_links.left())
1211 && utils::get_link_parity(y_links.right())
1212 } else {
1213 // If Y has even rank parity, it can only be a 2,2 node if it is
1214 // a binary node and both of its children have even parity.
1215 let y_left_links = y_links.left().map(|l| unsafe { T::links(l).as_ref() });
1216 let y_right_links = y_links.right().map(|r| unsafe { T::links(r).as_ref() });
1217
1218 y_left_links.is_some_and(|l| !l.rank_parity())
1219 && y_right_links.is_some_and(|l| !l.rank_parity())
1220 };
1221
1222 if y_is_22_node {
1223 y_links.demote();
1224 z_links.demote();
1225 } else {
1226 // At this point we know that y is neither a 2-child nor a 2,2 node
1227 // and give the loop conditions above this means we're done with promotions.
1228 // x still might be a 3-child, but that will be fixed with rotations below.
1229 break;
1230 }
1231 }
1232
1233 if let Some(parent) = z_links.parent() {
1234 // climbing up
1235 x = Some(z);
1236 z = parent;
1237 z_links = unsafe { T::links(z).as_mut() };
1238 } else {
1239 // we reached the root so were done rebalancing
1240 return;
1241 }
1242
1243 if !creates_3_node {
1244 return;
1245 }
1246 }
1247
1248 // Step 2: Rotation
1249 let (y, y_side) = get_sibling(x, z);
1250 let y_links = unsafe { T::links(y.unwrap()).as_mut() };
1251
1252 let v = y_links.child(y_side.opposite());
1253 let w = y_links.child(y_side);
1254
1255 if utils::get_link_parity(w) != y_links.rank_parity() {
1256 self.rotate_at(y.unwrap(), y_side.opposite());
1257
1258 y_links.promote();
1259 z_links.demote();
1260
1261 if z_links.is_leaf() {
1262 z_links.demote();
1263 }
1264 } else {
1265 let v = v.unwrap();
1266 let v_links = unsafe { T::links(v).as_mut() };
1267
1268 self.double_rotate_at(v, y_side.opposite());
1269
1270 v_links.double_promote();
1271 y_links.demote();
1272 z_links.double_demote();
1273 }
1274 }
1275
1276 fn rebalance_after_remove_2_2_leaf(&mut self, x: NonNull<T>) {
1277 // If we just turned node into a 2,2 leaf, it will have no children and
1278 // odd rank-parity.
1279 let x_links = unsafe { T::links(x).as_mut() };
1280
1281 if !x_links.rank_parity() || x_links.left().is_some() || x_links.right().is_some() {
1282 return;
1283 }
1284
1285 if let Some(parent) = x_links.parent()
1286 && crate::utils::node_is_2_child(x, parent)
1287 {
1288 // Demote the node turning it into a 1,1 leaf.
1289 x_links.demote();
1290
1291 // By demoting this node, we just created a 3-child so we need to deal with that.
1292 self.rebalance_after_remove_3_child(Some(x), parent);
1293 } else {
1294 // Demote the node turning it into a 1,1 leaf.
1295 x_links.demote();
1296 }
1297 }
1298
1299 fn rotate_at(&mut self, mut x: NonNull<T>, side: Side) {
1300 let x_links = unsafe { T::links(x).as_mut() };
1301 let y = x_links.child(side);
1302 let z = x_links.parent().unwrap();
1303 let z_links = unsafe { T::links(z).as_mut() };
1304 let p_z = z_links.parent();
1305
1306 T::after_rotate(
1307 unsafe { Pin::new_unchecked(x.as_mut()) },
1308 z,
1309 get_sibling(Some(x), z).0,
1310 y,
1311 side,
1312 );
1313
1314 // Rotate X into place
1315 x_links.replace_parent(p_z);
1316 if let Some(p_z) = p_z {
1317 let p_z_links = unsafe { T::links(p_z).as_mut() };
1318
1319 if p_z_links.left() == Some(z) {
1320 p_z_links.replace_left(Some(x));
1321 } else {
1322 p_z_links.replace_right(Some(x));
1323 }
1324 } else {
1325 self.root = Some(x);
1326 }
1327
1328 // make z the `side`-child of x
1329 x_links.replace_child(side, Some(z));
1330 z_links.replace_parent(Some(x));
1331
1332 // make y the `opposite side`-child of z
1333 z_links.replace_child(side.opposite(), y);
1334 if let Some(y) = y {
1335 unsafe { T::links(y).as_mut() }.replace_parent(Some(z));
1336 }
1337 }
1338
1339 fn double_rotate_at(&mut self, mut y: NonNull<T>, side: Side) {
1340 let y_links = unsafe { T::links(y).as_mut() };
1341
1342 let x = y_links.parent().unwrap();
1343 let x_links = unsafe { T::links(x).as_ref() };
1344 let z = x_links.parent().unwrap();
1345 let z_links = unsafe { T::links(z).as_ref() };
1346 let p_z = z_links.parent();
1347
1348 T::after_rotate(
1349 unsafe { Pin::new_unchecked(y.as_mut()) },
1350 x,
1351 get_sibling(Some(y), x).0,
1352 y_links.child(side.opposite()),
1353 side.opposite(),
1354 );
1355 T::after_rotate(
1356 unsafe { Pin::new_unchecked(y.as_mut()) },
1357 z,
1358 get_sibling(Some(x), z).0,
1359 y_links.child(side),
1360 side,
1361 );
1362
1363 // Rotate Y into place
1364 y_links.replace_parent(p_z);
1365 if let Some(p_z) = p_z {
1366 let p_z_links = unsafe { T::links(p_z).as_mut() };
1367
1368 if p_z_links.left() == Some(z) {
1369 p_z_links.replace_left(Some(y));
1370 } else {
1371 p_z_links.replace_right(Some(y));
1372 }
1373 } else {
1374 self.root = Some(y);
1375 }
1376
1377 let mut move_subtrees = |lt: NonNull<T>, gt: NonNull<T>| {
1378 let lt_links = unsafe { T::links(lt).as_mut() };
1379 let gt_links = unsafe { T::links(gt).as_mut() };
1380
1381 // Move y's left subtree (since lt > left(y)) to lt's right subtree
1382 lt_links.replace_right(y_links.left());
1383
1384 if let Some(left) = y_links.left() {
1385 unsafe { T::links(left).as_mut() }.replace_parent(Some(lt));
1386 }
1387
1388 y_links.replace_left(Some(lt));
1389 lt_links.replace_parent(Some(y));
1390
1391 // Move y's right subtree (since gt > right(y)) to gt's left subtree
1392 gt_links.replace_left(y_links.right());
1393
1394 if let Some(right) = y_links.right() {
1395 unsafe { T::links(right).as_mut() }.replace_parent(Some(gt));
1396 }
1397
1398 y_links.replace_right(Some(gt));
1399 gt_links.replace_parent(Some(y));
1400 };
1401
1402 match side {
1403 Side::Left => move_subtrees(z, x),
1404 Side::Right => move_subtrees(x, z),
1405 }
1406 }
1407
1408 fn swap_in_node_at(&mut self, old: NonNull<T>, new: NonNull<T>) {
1409 let old_links = unsafe { T::links(old).as_mut() };
1410 let new_links = unsafe { T::links(new).as_mut() };
1411
1412 let parent = old_links.parent();
1413 let left = old_links.left();
1414 let right = old_links.right();
1415
1416 new_links.replace_parent(parent);
1417 if let Some(parent) = parent {
1418 let parent_links = unsafe { T::links(parent).as_mut() };
1419 if parent_links.left() == Some(old) {
1420 parent_links.replace_left(Some(new));
1421 } else {
1422 parent_links.replace_right(Some(new));
1423 }
1424 } else {
1425 self.root = Some(new);
1426 }
1427
1428 new_links.replace_left(left);
1429 if let Some(left) = left {
1430 unsafe { T::links(left).as_mut() }.replace_parent(Some(new));
1431 }
1432 old_links.replace_left(None);
1433
1434 new_links.replace_right(right);
1435 if let Some(right) = right {
1436 unsafe { T::links(right).as_mut() }.replace_parent(Some(new));
1437 }
1438 old_links.replace_right(None);
1439
1440 // update parity
1441 new_links.set_rank(old_links);
1442
1443 old_links.replace_parent(None);
1444 }
1445}
1446
1447/// Links to other nodes in a [`WAVLTree`].
1448///
1449/// In order to be part of a [`WAVLTree`], a type must contain an instance of this type, and must implement the [`Linked`] trait.
1450///
1451/// # Debug assertions
1452///
1453/// With debug assertions enabled, `Links` also keeps track of the nodes rank, this is so
1454/// `WAVLTree::assert_valid` can assert the WAVL rank balancing rules. This increases the size of
1455/// `Links` by an additional `usize`
1456pub struct Links<T: ?Sized> {
1457 inner: UnsafeCell<LinksInner<T>>,
1458}
1459
1460struct LinksInner<T: ?Sized> {
1461 rank_parity: bool,
1462 up: Link<T>,
1463 left: Link<T>,
1464 right: Link<T>,
1465 #[cfg(debug_assertions)]
1466 rank: usize,
1467 /// Linked list links must always be `!Unpin`, in order to ensure that they
1468 /// never receive LLVM `noalias` annotations; see also
1469 /// <https://github.com/rust-lang/rust/issues/63818>.
1470 _unpin: PhantomPinned,
1471}
1472
1473impl<T: ?Sized> Default for Links<T> {
1474 fn default() -> Self {
1475 Self::new()
1476 }
1477}
1478
1479impl<T: ?Sized> fmt::Debug for Links<T> {
1480 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1481 let mut f = f.debug_struct("Links");
1482
1483 f.field("self", &format_args!("{self:p}"))
1484 .field("rank_parity", &self.rank_parity())
1485 .field("parent", &self.parent())
1486 .field("left", &self.left())
1487 .field("right", &self.left());
1488
1489 #[cfg(debug_assertions)]
1490 f.field("rank", &self.rank());
1491
1492 f.finish()
1493 }
1494}
1495
1496impl<T: ?Sized> Links<T> {
1497 /// Returns new links for a [Weak AVL tree][WAVLTree].
1498 #[must_use]
1499 pub const fn new() -> Self {
1500 Self {
1501 inner: UnsafeCell::new(LinksInner {
1502 rank_parity: false, // nodes start out as leaves with rank 0, even parity
1503 #[cfg(debug_assertions)]
1504 rank: 0,
1505 up: None,
1506 left: None,
1507 right: None,
1508 _unpin: PhantomPinned,
1509 }),
1510 }
1511 }
1512
1513 /// Returns `true` if this node is currently linked to a [WAVLTree].
1514 pub fn is_linked(&self) -> bool {
1515 let inner = unsafe { &*self.inner.get() };
1516 inner.up.is_some() || inner.left.is_some() || inner.right.is_some()
1517 }
1518
1519 /// Forcefully unlinks this node from the tree.
1520 ///
1521 /// # Safety
1522 ///
1523 /// Calling this method on a node that is linked to a tree, **will corrupt the tree** leaving
1524 /// pointers to arbitrary memory around.
1525 unsafe fn unlink(&mut self) {
1526 self.inner.get_mut().up = None;
1527 self.inner.get_mut().left = None;
1528 self.inner.get_mut().right = None;
1529 self.inner.get_mut().rank_parity = false;
1530 }
1531
1532 #[inline]
1533 pub fn parent(&self) -> Link<T> {
1534 unsafe { (*self.inner.get()).up }
1535 }
1536 #[inline]
1537 pub fn left(&self) -> Link<T> {
1538 unsafe { (*self.inner.get()).left }
1539 }
1540 #[inline]
1541 pub fn right(&self) -> Link<T> {
1542 unsafe { (*self.inner.get()).right }
1543 }
1544
1545 #[inline]
1546 pub fn replace_parent(&mut self, lk: Link<T>) -> Link<T> {
1547 mem::replace(&mut self.inner.get_mut().up, lk)
1548 }
1549 #[inline]
1550 pub fn replace_left(&mut self, lk: Link<T>) -> Link<T> {
1551 mem::replace(&mut self.inner.get_mut().left, lk)
1552 }
1553 #[inline]
1554 pub fn replace_right(&mut self, lk: Link<T>) -> Link<T> {
1555 mem::replace(&mut self.inner.get_mut().right, lk)
1556 }
1557
1558 #[inline]
1559 #[cfg(debug_assertions)]
1560 fn rank(&self) -> usize {
1561 unsafe { (*self.inner.get()).rank }
1562 }
1563 #[inline]
1564 fn rank_parity(&self) -> bool {
1565 unsafe { (*self.inner.get()).rank_parity }
1566 }
1567 // TODO test
1568 #[inline]
1569 fn promote(&mut self) {
1570 self.inner.get_mut().rank_parity = !self.rank_parity();
1571 #[cfg(debug_assertions)]
1572 {
1573 self.inner.get_mut().rank += 1;
1574 }
1575 }
1576 // TODO test
1577 #[inline]
1578 fn demote(&mut self) {
1579 self.inner.get_mut().rank_parity = !self.rank_parity();
1580 #[cfg(debug_assertions)]
1581 {
1582 self.inner.get_mut().rank -= 1;
1583 }
1584 }
1585 #[inline]
1586 fn double_promote(&mut self) {
1587 #[cfg(debug_assertions)]
1588 {
1589 self.inner.get_mut().rank += 2;
1590 }
1591 }
1592 #[inline]
1593 fn double_demote(&mut self) {
1594 #[cfg(debug_assertions)]
1595 {
1596 self.inner.get_mut().rank -= 2;
1597 }
1598 }
1599 fn set_rank(&mut self, other: &Self) {
1600 self.inner.get_mut().rank_parity = other.rank_parity();
1601 #[cfg(debug_assertions)]
1602 {
1603 self.inner.get_mut().rank = other.rank();
1604 }
1605 }
1606
1607 pub fn is_leaf(&self) -> bool {
1608 self.left().is_none() && self.right().is_none()
1609 }
1610
1611 #[inline]
1612 fn child(&self, side: Side) -> Link<T> {
1613 match side {
1614 Side::Left => unsafe { (*self.inner.get()).left },
1615 Side::Right => unsafe { (*self.inner.get()).right },
1616 }
1617 }
1618 #[inline]
1619 fn replace_child(&mut self, side: Side, child: Link<T>) -> Link<T> {
1620 match side {
1621 Side::Left => mem::replace(&mut self.inner.get_mut().left, child),
1622 Side::Right => mem::replace(&mut self.inner.get_mut().right, child),
1623 }
1624 }
1625
1626 /// Asserts as many invariants about this particular node as possible.
1627 ///
1628 /// # Panics
1629 ///
1630 /// Panics when an assertion does not hold.
1631 #[track_caller]
1632 pub fn assert_valid(&self)
1633 where
1634 T: Linked,
1635 {
1636 if let Some(parent) = self.parent() {
1637 assert_ne!(
1638 unsafe { T::links(parent) },
1639 NonNull::from(self),
1640 "node's parent cannot be itself; node={self:#?}"
1641 );
1642 }
1643
1644 if let Some(left) = self.left() {
1645 assert_ne!(
1646 unsafe { T::links(left) },
1647 NonNull::from(self),
1648 "node's left child cannot be itself; node={self:#?}"
1649 );
1650 }
1651
1652 if let Some(right) = self.right() {
1653 assert_ne!(
1654 unsafe { T::links(right) },
1655 NonNull::from(self),
1656 "node's right child cannot be itself; node={self:#?}"
1657 );
1658 }
1659 if let (Some(parent), Some(left)) = (self.parent(), self.left()) {
1660 assert_ne!(
1661 unsafe { T::links(parent) },
1662 unsafe { T::links(left) },
1663 "node's parent and left child cannot be the same; node={self:#?}"
1664 );
1665 }
1666 if let (Some(parent), Some(right)) = (self.parent(), self.right()) {
1667 assert_ne!(
1668 unsafe { T::links(parent) },
1669 unsafe { T::links(right) },
1670 "node's parent and right child cannot be the same; node={self:#?}"
1671 );
1672 }
1673 if let (Some(left), Some(right)) = (self.left(), self.right()) {
1674 assert_ne!(
1675 unsafe { T::links(left) },
1676 unsafe { T::links(right) },
1677 "node's left and right children cannot be the same; node={self:#?}"
1678 );
1679 }
1680 }
1681}
1682
1683#[cfg(test)]
1684mod tests {
1685 extern crate alloc;
1686
1687 use super::*;
1688 use alloc::boxed::Box;
1689 use alloc::vec::Vec;
1690 use core::mem::offset_of;
1691 use core::pin::Pin;
1692 use rand::prelude::SliceRandom;
1693 use rand::rng;
1694
1695 #[derive(Default)]
1696 struct TestEntry {
1697 value: usize,
1698 links: Links<Self>,
1699 }
1700 impl TestEntry {
1701 pub fn new(value: usize) -> Self {
1702 let mut this = Self::default();
1703 this.value = value;
1704 this
1705 }
1706 }
1707 impl fmt::Debug for TestEntry {
1708 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1709 f.debug_struct("PlaceHolderEntry")
1710 .field("value", &self.value)
1711 .finish()
1712 }
1713 }
1714 unsafe impl Linked for TestEntry {
1715 /// Any heap-allocated type that owns an element may be used.
1716 ///
1717 /// An element *must not* move while part of an intrusive data
1718 /// structure. In many cases, `Pin` may be used to enforce this.
1719 type Handle = Pin<Box<Self>>;
1720
1721 type Key = usize;
1722
1723 /// Convert an owned `Handle` into a raw pointer
1724 fn into_ptr(handle: Self::Handle) -> NonNull<Self> {
1725 unsafe { NonNull::from(Box::leak(Pin::into_inner_unchecked(handle))) }
1726 }
1727
1728 /// Convert a raw pointer back into an owned `Handle`.
1729 unsafe fn from_ptr(ptr: NonNull<Self>) -> Self::Handle {
1730 // Safety: `NonNull` *must* be constructed from a pinned reference
1731 // which the tree implementation upholds.
1732 unsafe { Pin::new_unchecked(Box::from_raw(ptr.as_ptr())) }
1733 }
1734
1735 unsafe fn links(ptr: NonNull<Self>) -> NonNull<Links<Self>> {
1736 ptr.map_addr(|addr| {
1737 let offset = offset_of!(Self, links);
1738 addr.checked_add(offset).unwrap()
1739 })
1740 .cast()
1741 }
1742
1743 fn get_key(&self) -> &Self::Key {
1744 &self.value
1745 }
1746 }
1747
1748 #[cfg(not(target_os = "none"))]
1749 #[test]
1750 fn random_inserts_and_removals() {
1751 let mut tree: WAVLTree<TestEntry> = WAVLTree::new();
1752
1753 let mut rng = rng();
1754
1755 let mut nums = (0..30).collect::<Vec<_>>();
1756 nums.shuffle(&mut rng);
1757
1758 println!("inserts {nums:?}");
1759 for i in nums.clone() {
1760 println!("=== inserting {i}");
1761 tree.insert(Box::pin(TestEntry::new(i)));
1762 println!("=== inserted {i}");
1763 }
1764
1765 nums.shuffle(&mut rng);
1766
1767 println!("deletions {nums:?}");
1768 for i in nums {
1769 println!("=== removing {i}");
1770 tree.remove(&i);
1771 // println!("{}", tree.dot());
1772 println!("=== removed {i}");
1773 }
1774 }
1775
1776 #[cfg(not(target_os = "none"))]
1777 #[test]
1778 fn random_inserts_and_searches() {
1779 let mut tree: WAVLTree<TestEntry> = WAVLTree::new();
1780
1781 let mut rng = rng();
1782
1783 let mut nums = (0..50).collect::<Vec<_>>();
1784 nums.shuffle(&mut rng);
1785
1786 println!("inserts {nums:?}");
1787 for i in nums.clone() {
1788 println!("=== inserting {i}");
1789 tree.insert(Box::pin(TestEntry::new(i)));
1790 println!("=== inserted {i}");
1791 }
1792
1793 nums.shuffle(&mut rng);
1794
1795 println!("searches {nums:?}");
1796 for i in nums {
1797 println!("=== searching {i}");
1798
1799 match tree.entry(&i) {
1800 Entry::Occupied(e) => assert_eq!(i, e.get().value),
1801 Entry::Vacant(_) => panic!(),
1802 }
1803 // println!("{}", tree.dot());
1804 println!("=== found {i}");
1805 }
1806 }
1807
1808 #[cfg(not(target_os = "none"))]
1809 #[test]
1810 fn range() {
1811 let mut tree: WAVLTree<TestEntry> = WAVLTree::new();
1812
1813 for i in 0..16 {
1814 let i = i * 2;
1815 println!("=== inserting {i}");
1816 tree.insert(Box::pin(TestEntry::new(i)));
1817 println!("=== inserted {i}");
1818 }
1819
1820 for i in tree.range(4..=6) {
1821 println!("range iter {i:?}");
1822 }
1823 }
1824
1825 #[cfg(not(target_os = "none"))]
1826 #[test]
1827 fn entry_next() {
1828 let mut tree: WAVLTree<TestEntry> = WAVLTree::new();
1829
1830 tree.insert(Box::pin(TestEntry::new(1000)));
1831 tree.insert(Box::pin(TestEntry::new(3000)));
1832
1833 let entry = tree.entry(&2000);
1834 assert!(matches!(entry, Entry::Vacant(_)));
1835
1836 assert_eq!(entry.peek_next().unwrap().value, 3000);
1837 }
1838
1839 #[cfg(not(target_os = "none"))]
1840 #[test]
1841 fn into_iter() {
1842 let mut tree: WAVLTree<TestEntry> = WAVLTree::new();
1843
1844 tree.insert(Box::pin(TestEntry::new(1000)));
1845 tree.insert(Box::pin(TestEntry::new(3000)));
1846 tree.insert(Box::pin(TestEntry::new(500)));
1847
1848 let mut iter = tree.into_iter();
1849 assert_eq!(iter.next().unwrap().value, 500);
1850 assert_eq!(iter.next().unwrap().value, 1000);
1851 assert_eq!(iter.next().unwrap().value, 3000);
1852 }
1853
1854 #[cfg(not(target_os = "none"))]
1855 #[test]
1856 fn into_iter_back() {
1857 let mut tree: WAVLTree<TestEntry> = WAVLTree::new();
1858
1859 tree.insert(Box::pin(TestEntry::new(1000)));
1860 tree.insert(Box::pin(TestEntry::new(3000)));
1861 tree.insert(Box::pin(TestEntry::new(500)));
1862
1863 let mut iter = tree.into_iter();
1864 assert_eq!(iter.next_back().unwrap().value, 3000);
1865 assert_eq!(iter.next_back().unwrap().value, 1000);
1866 assert_eq!(iter.next_back().unwrap().value, 500);
1867 }
1868}