Next Generation WASM Microkernel Operating System
at trap_handler 1868 lines 63 kB view raw
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}