Skip to main content

embed_collections/btree/
mod.rs

1//! B+Tree Map - A in memory cache-optimized B+Tree for single-threaded use.
2//!
3//! ## Feature outlines
4//! - Designed for CPU cache efficiency and memory efficiency
5//! - Optimised for numeric key type
6//!   - Typical scenario: [range-tree-rs](https://docs.rs/range-tree-rs)
7//! - A B+tree. Data stores only at leaf level, with links at leaf level.
8//!   - Provides efficient iteration of data
9//!   - Linear search within nodes, respecting cacheline boundaries
10//! - Nodes are filled up in 4 cache lines (256 bytes on x86_64)
11//!   - keys stored in first 128B (with header)
12//!   - Values/pointers stored in last 128B
13//!   - the capacity is calculated according to the size of K, V, with limitations:
14//!     - K & V should <= CACHE_LINE_SIZE - 16  (If K & V is larger should put into `Box`)
15//! - Specially Entry API which allow to modify after moving the cursor to adjacent data.
16//! - The detail design notes are with the source in mod.rs and node.rs
17//!
18//! ## Special APIs
19//!
20//! batch removal:
21//! - [BTreeMap::remove_range()]
22//! - [BTreeMap::remove_range_with()]
23//!
24//! adjacent entry:
25//! - [Entry::peak_forward()]
26//! - [Entry::peak_backward()]
27//! - [Entry::move_forward()]
28//! - [Entry::move_backward()]
29//! - [VacantEntry::peak_forward()]
30//! - [VacantEntry::peak_backward()]
31//! - [VacantEntry::move_forward()]
32//! - [VacantEntry::move_backward()]
33//! - [OccupiedEntry::peak_forward()]
34//! - [OccupiedEntry::peak_backward()]
35//! - [OccupiedEntry::move_forward()]
36//! - [OccupiedEntry::move_backward()]
37//! - [OccupiedEntry::alter_key()]
38
39/*
40
41# Designer notes
42
43 Target scenario:  To maintain slab tree for disk, lets say 1 billion nodes, this design is aim for high fan-out.
44
45 Since There're no parent pointer, no fence keys. So we maintain a cache to accelerate the look
46 up for parent nodes.
47 Since we support combining cursor moving in Entry API (try to merge with previous or next adjacent
48 node). But user can call `remove()` on moved cursor.
49
50## Acceleration Search for finding the parent using PathCache
51
52- Assume PathCache is for Node A, Node B is the right brother of node A. A's ptr is at ParentA[idx]
53  - To find parent for Node B
54    - If idx < last (Cap - 1), then A and B has common parent,
55    - otherwise A and B have no common parent. Should continue iteration to upper PathCache. There will be common ancestor until idx < last
56
57- Assume PathCache is for Node B, Node A is the left brother of node B, B's ptr is at ParentB[idx]
58  - To find parent for Node A
59    - If idx > 0, then A and B has common parent.
60    - otherwise A and B have no common parent. Should continue iteration to upper PathCache. There will be common ancestor until idx > 0
61
62## Rebalance
63
64- When insert on a full LeafNode, we try to move items to left/right brother, to delay split operation.
65
66- One entry removed, current node usage < 50% (the threshold can be adjust according to tree size)
67
68  - we don't need to borrow data from brothers (to avoid trashing), and we have already done borrowing on insert.
69
70  - try to merge data, with left + current < cap, or current + right < cap, or left + current + right == 2 * cap
71
72  - No need to mere 3 -> 1, because before reaching 30% average usage, we already checked 3 -> 2.
73
74- The threshold to check merge for InterNode can be lower (like 30%), to avoid trashing
75
76
77## Future ideas
78
79- dynamically incress InterNode size, or variable size
80- borrow from leaf / right on InterNode split, increase fill ratio to 80%
81- 2 - 3 split (increase fill ratio to 90%)
82*/
83
84use core::borrow::Borrow;
85use core::cell::UnsafeCell;
86use core::fmt::Debug;
87use core::ops::{Bound, RangeBounds};
88mod entry;
89pub use entry::*;
90mod node;
91use node::*;
92mod inter;
93use inter::*;
94mod leaf;
95use leaf::*;
96mod iter;
97#[allow(unused_imports)]
98use crate::{print_log, trace_log};
99use iter::RangeBase;
100pub use iter::{IntoIter, Iter, IterMut, Keys, Range, RangeMut, Values, ValuesMut};
101
102#[cfg(test)]
103mod tests;
104
105/// B+Tree Map for single-threaded usage, optimized for numeric type.
106pub struct BTreeMap<K: Ord + Clone + Sized, V: Sized> {
107    /// Root node (may be null for empty tree)
108    root: Option<Node<K, V>>,
109    /// Number of elements in the tree
110    len: usize,
111    // use unsafe to avoid borrow problems
112    cache: UnsafeCell<PathCache<K, V>>,
113    // count of leaf nodes
114    leaf_count: usize,
115    #[cfg(all(test, feature = "trace_log"))]
116    triggers: u32,
117}
118
119#[cfg(all(test, feature = "trace_log"))]
120#[repr(u32)]
121enum TestFlag {
122    LeafSplit = 1,
123    InterSplit = 1 << 1,
124    LeafMoveLeft = 1 << 2,
125    LeafMoveRight = 1 << 3,
126    LeafMergeLeft = 1 << 4,
127    LeafMergeRight = 1 << 5,
128    InterMoveLeft = 1 << 6,
129    InterMoveLeftFirst = 1 << 7,
130    InterMoveRight = 1 << 8,
131    InterMoveRightLast = 1 << 9,
132    InterMergeLeft = 1 << 10,
133    InterMergeRight = 1 << 11,
134    UpdateSepKey = 1 << 12,
135    RemoveOnlyChild = 1 << 13,
136    RemoveChildFirst = 1 << 14,
137    RemoveChildMid = 1 << 15,
138    RemoveChildLast = 1 << 16,
139}
140
141unsafe impl<K: Ord + Clone + Sized + Send, V: Sized + Send> Send for BTreeMap<K, V> {}
142unsafe impl<K: Ord + Clone + Sized + Send, V: Sized + Send> Sync for BTreeMap<K, V> {}
143
144#[cfg(feature = "std")]
145impl<K: Ord + Clone + Sized, V: Sized> std::panic::RefUnwindSafe for BTreeMap<K, V> {}
146
147impl<K: Ord + Sized + Clone, V: Sized> BTreeMap<K, V> {
148    /// Create a new empty BTreeMap
149    pub fn new() -> Self {
150        Self {
151            root: None,
152            len: 0,
153            cache: UnsafeCell::new(PathCache::<K, V>::new()),
154            leaf_count: 0,
155            #[cfg(all(test, feature = "trace_log"))]
156            triggers: 0,
157        }
158    }
159
160    /// Returns the number of elements in the map
161    #[inline(always)]
162    pub fn len(&self) -> usize {
163        self.len
164    }
165
166    /// Returns true if the map is empty
167    #[inline(always)]
168    pub fn is_empty(&self) -> bool {
169        self.len == 0
170    }
171
172    /// return (cap_of_inter_node, cap_of_leaf_node)
173    #[inline]
174    pub const fn cap() -> (u32, u32) {
175        let inter_cap = InterNode::<K, V>::cap();
176        let leaf_cap = LeafNode::<K, V>::cap();
177        (inter_cap, leaf_cap)
178    }
179
180    /// Return the number of leaf nodes
181    #[inline]
182    pub fn leaf_count(&self) -> usize {
183        self.leaf_count
184    }
185
186    #[cfg(all(test, feature = "std", feature = "trace_log"))]
187    pub fn print_trigger_flags(&self) {
188        let mut s = String::from("");
189        if self.triggers & TestFlag::InterSplit as u32 > 0 {
190            s += "InterSplit,";
191        }
192        if self.triggers & TestFlag::LeafSplit as u32 > 0 {
193            s += "LeafSplit,";
194        }
195        if self.triggers & TestFlag::LeafMoveLeft as u32 > 0 {
196            s += "LeafMoveLeft,";
197        }
198        if self.triggers & TestFlag::LeafMoveRight as u32 > 0 {
199            s += "LeafMoveRight,";
200        }
201        if self.triggers & TestFlag::InterMoveLeft as u32 > 0 {
202            s += "InterMoveLeft,";
203        }
204        if self.triggers & TestFlag::InterMoveRight as u32 > 0 {
205            s += "InterMoveRight,";
206        }
207        if s.len() > 0 {
208            print_log!("{s}");
209        }
210        let mut s = String::from("");
211        if self.triggers & TestFlag::InterMergeLeft as u32 > 0 {
212            s += "InterMergeLeft,";
213        }
214        if self.triggers & TestFlag::InterMergeRight as u32 > 0 {
215            s += "InterMergeRight,";
216        }
217        if self.triggers & TestFlag::RemoveOnlyChild as u32 > 0 {
218            s += "RemoveOnlyChild,";
219        }
220        if self.triggers
221            & (TestFlag::RemoveChildFirst as u32
222                | TestFlag::RemoveChildMid as u32
223                | TestFlag::RemoveChildLast as u32)
224            > 0
225        {
226            s += "RemoveChild,";
227        }
228        if s.len() > 0 {
229            print_log!("{s}");
230        }
231    }
232
233    /// Return the average fill ratio of leaf nodes
234    ///
235    /// The range is [0.0, 100]
236    #[inline]
237    pub fn get_fill_ratio(&self) -> f32 {
238        if self.len == 0 {
239            0.0
240        } else {
241            let cap = LeafNode::<K, V>::cap() as usize * self.leaf_count;
242            self.len as f32 / cap as f32 * 100.0
243        }
244    }
245
246    /// When root is leaf, returns 1, otherwise return the number of layers of inter node
247    #[inline(always)]
248    pub fn height(&self) -> u32 {
249        if let Some(Node::Inter(node)) = &self.root {
250            return node.height() + 1;
251        }
252        1
253    }
254
255    #[inline(always)]
256    fn get_cache(&self) -> &mut PathCache<K, V> {
257        unsafe { (&mut *self.cache.get()) as _ }
258    }
259
260    /// Returns an entry to the key in the map
261    #[inline]
262    pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
263        let cache = self.get_cache();
264        cache.clear();
265        let leaf = match &self.root {
266            None => return Entry::Vacant(VacantEntry { tree: self, key, idx: 0, leaf: None }),
267            Some(root) => root.find_leaf_with_cache(cache, &key),
268        };
269        let (idx, is_equal) = leaf.search(&key);
270        if is_equal {
271            Entry::Occupied(OccupiedEntry { tree: self, idx, leaf })
272        } else {
273            Entry::Vacant(VacantEntry { tree: self, key, idx, leaf: Some(leaf) })
274        }
275    }
276
277    #[inline(always)]
278    fn find<Q>(&self, key: &Q) -> Option<(LeafNode<K, V>, u32)>
279    where
280        K: Borrow<Q>,
281        Q: Ord + ?Sized,
282    {
283        let leaf = match &self.root {
284            None => return None,
285            Some(root) => root.find_leaf(key),
286        };
287        let (idx, is_equal) = leaf.search(key);
288        trace_log!("find leaf {leaf:?} {idx} exist {is_equal}");
289        if is_equal { Some((leaf, idx)) } else { None }
290    }
291
292    /// Returns true if the map contains the key
293    #[inline(always)]
294    pub fn contains_key<Q>(&self, key: &Q) -> bool
295    where
296        K: Borrow<Q>,
297        Q: Ord + ?Sized,
298    {
299        self.find::<Q>(key).is_some()
300    }
301
302    /// Returns a reference to the value corresponding to the key
303    pub fn get<Q>(&self, key: &Q) -> Option<&V>
304    where
305        K: Borrow<Q>,
306        Q: Ord + ?Sized,
307    {
308        if let Some((leaf, idx)) = self.find::<Q>(key) {
309            let value = unsafe { leaf.value_ptr(idx) };
310            debug_assert!(!value.is_null());
311            Some(unsafe { (*value).assume_init_ref() })
312        } else {
313            None
314        }
315    }
316
317    /// Returns a mutable reference to the value corresponding to the key
318    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
319    where
320        K: Borrow<Q>,
321        Q: Ord + ?Sized,
322    {
323        if let Some((leaf, idx)) = self.find::<Q>(key) {
324            let value = unsafe { leaf.value_ptr(idx) };
325            debug_assert!(!value.is_null());
326            Some(unsafe { (*value).assume_init_mut() })
327        } else {
328            None
329        }
330    }
331
332    /// Insert a key-value pair into the map
333    /// Returns the old value if the key already existed
334    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
335        // use entry api to insert
336        match self.entry(key) {
337            Entry::Occupied(mut entry) => Some(entry.insert(value)),
338            Entry::Vacant(entry) => {
339                entry.insert(value);
340                None
341            }
342        }
343    }
344
345    /// Remove a key from the map, returning the value if it existed
346    pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
347    where
348        K: Borrow<Q>,
349        Q: Ord + ?Sized,
350    {
351        if let Some(root) = &self.root {
352            let cache = self.get_cache();
353            cache.clear();
354            let mut leaf = root.find_leaf_with_cache::<Q>(cache, key);
355            let (idx, is_equal) = leaf.search(key);
356            if is_equal {
357                trace_log!("{leaf:?} remove {idx}");
358                let val = leaf.remove_value_no_borrow(idx);
359                self.len -= 1;
360                // Check for underflow and handle merge
361                let new_count = leaf.key_count();
362                let min_count = LeafNode::<K, V>::cap() >> 1;
363                if new_count < min_count && !root.is_leaf() {
364                    // The cache should already contain the path from the entry lookup
365                    self.handle_leaf_underflow(leaf, true);
366                }
367                Some(val)
368            } else {
369                None
370            }
371        } else {
372            None
373        }
374    }
375
376    /// Perform removal in batch mode and return the last item removed
377    ///
378    /// NOTE: this function speed up by skipping the underflow of LeafNode until the last operation.
379    pub fn remove_range<R>(&mut self, range: R) -> Option<(K, V)>
380    where
381        R: RangeBounds<K>,
382    {
383        self.remove_range_with::<R, _>(range, |_, _| {})
384    }
385
386    /// Perform removal in batch mode and return the last item removed
387    ///
388    /// On each removal, callback function `cb` is invoke with (ref of key, ref of value)
389    ///
390    /// NOTE: this function speed up by skipping the underflow of LeafNode until the last operation.
391    #[inline]
392    pub fn remove_range_with<R, F>(&mut self, range: R, mut cb: F) -> Option<(K, V)>
393    where
394        R: RangeBounds<K>,
395        F: FnMut(&K, &V),
396    {
397        macro_rules! end_contains {
398            ($key: expr) => {{
399                match range.end_bound() {
400                    Bound::Excluded(k) => $key < k,
401                    Bound::Included(k) => $key <= k,
402                    Bound::Unbounded => true,
403                }
404            }};
405        }
406        // Note: do not use find_leaf_with_bound, it's a different behavior
407        let mut ent = match range.start_bound() {
408            Bound::Excluded(k) => match self.entry(k.clone()).move_forward() {
409                Ok(ent) => {
410                    if end_contains!(ent.key()) {
411                        ent
412                    } else {
413                        return None;
414                    }
415                }
416                Err(_) => return None,
417            },
418            Bound::Included(k) => match self.entry(k.clone()) {
419                Entry::Occupied(ent) => ent,
420                Entry::Vacant(ent) => match ent.move_forward() {
421                    Ok(ent) => {
422                        if end_contains!(ent.key()) {
423                            ent
424                        } else {
425                            return None;
426                        }
427                    }
428                    Err(_) => return None,
429                },
430            },
431            Bound::Unbounded => {
432                if let Some(ent) = self.first_entry() {
433                    ent
434                } else {
435                    return None;
436                }
437            }
438        };
439        loop {
440            if let Some((_next_k, _next_v)) = ent.peak_forward() {
441                if end_contains!(_next_k) {
442                    let next_key = _next_k.clone();
443                    let (_k, _v) = ent._remove_entry(false);
444                    cb(&_k, &_v);
445                    if let Entry::Occupied(_ent) = self.entry(next_key) {
446                        ent = _ent;
447                        continue;
448                    } else {
449                        unreachable!();
450                    }
451                }
452            }
453            let (_k, _v) = ent._remove_entry(true);
454            cb(&_k, &_v);
455            return Some((_k, _v));
456        }
457    }
458
459    #[inline(always)]
460    fn get_root_unwrap(&self) -> &Node<K, V> {
461        self.root.as_ref().unwrap()
462    }
463
464    /// update the separate_key in parent after borrowing space from left/right node
465    #[inline(always)]
466    fn update_ancestor_sep_key<const MOVE: bool>(&mut self, sep_key: K) {
467        // if idx == 0, this is the leftmost ptr in the InterNode, we go up until finding a
468        // split key
469        let ret = if MOVE {
470            self.get_cache()
471                .move_to_ancenstor(|_node, idx| -> bool { idx > 0 }, dummy_post_callback)
472        } else {
473            self.get_cache().peak_ancenstor(|_node, idx| -> bool { idx > 0 })
474        };
475        if let Some((parent, parent_idx)) = ret {
476            trace_log!("update_ancestor_sep_key move={MOVE} at {parent:?}:{}", parent_idx - 1);
477            #[cfg(all(test, feature = "trace_log"))]
478            {
479                self.triggers |= TestFlag::UpdateSepKey as u32;
480            }
481            parent.change_key(parent_idx - 1, sep_key);
482        }
483    }
484
485    /// Insert with split handling - called when leaf is full
486    fn insert_with_split(
487        &mut self, key: K, value: V, mut leaf: LeafNode<K, V>, idx: u32,
488    ) -> *mut V {
489        debug_assert!(leaf.is_full());
490        let cap = LeafNode::<K, V>::cap();
491        if idx < cap {
492            // random insert, try borrow space from left and right
493            if let Some(mut left_node) = leaf.get_left_node()
494                && !left_node.is_full()
495            {
496                trace_log!("insert {leaf:?}:{idx} borrow left {left_node:?}");
497                let val_p = if idx == 0 {
498                    // leaf is not change, but since the insert pos is leftmost of this node, mean parent
499                    // separate_key <= key, need to update its separate_key
500                    left_node.insert_no_split_with_idx(left_node.key_count(), key, value)
501                } else {
502                    leaf.insert_borrow_left(&mut left_node, idx, key, value)
503                };
504                #[cfg(all(test, feature = "trace_log"))]
505                {
506                    self.triggers |= TestFlag::LeafMoveLeft as u32;
507                }
508                self.update_ancestor_sep_key::<true>(leaf.clone_first_key());
509                return val_p;
510            }
511        } else {
512            // insert into empty new node, left is probably full, right is probably none
513        }
514        if let Some(mut right_node) = leaf.get_right_node()
515            && !right_node.is_full()
516        {
517            trace_log!("insert {leaf:?}:{idx} borrow right {right_node:?}");
518            let val_p = if idx == cap {
519                // leaf is not change, in this condition, right_node is the leftmost child
520                // of its parent, key < right_node.get_keys()[0]
521                right_node.insert_no_split_with_idx(0, key, value)
522            } else {
523                leaf.borrow_right(&mut right_node);
524                leaf.insert_no_split_with_idx(idx, key, value)
525            };
526            #[cfg(all(test, feature = "trace_log"))]
527            {
528                self.triggers |= TestFlag::LeafMoveRight as u32;
529            }
530            self.get_cache().move_right();
531            self.update_ancestor_sep_key::<true>(right_node.clone_first_key());
532            return val_p;
533        }
534        #[cfg(all(test, feature = "trace_log"))]
535        {
536            self.triggers |= TestFlag::LeafSplit as u32;
537        }
538        let (new_leaf, ptr_v) = leaf.insert_with_split(idx, key, value);
539        self.leaf_count += 1;
540        let split_key = unsafe { (*new_leaf.key_ptr(0)).assume_init_ref().clone() };
541        self.propagate_split(split_key, leaf.get_ptr(), new_leaf.get_ptr());
542        ptr_v
543    }
544
545    /// Propagate node split up the tree using iteration (non-recursive)
546    /// First tries to borrow space from left/right sibling before splitting
547    ///
548    /// left_ptr: existing child
549    /// right_ptr: new_child split from left_ptr
550    /// promote_key: sep_key to split left_ptr & right_ptr
551    #[inline(always)]
552    fn propagate_split(
553        &mut self, mut promote_key: K, mut left_ptr: *mut NodeHeader,
554        mut right_ptr: *mut NodeHeader,
555    ) {
556        let mut height = 0;
557        // If we have parent nodes in cache, process them iteratively
558        while let Some((mut parent, idx)) = self.get_cache().pop() {
559            if !parent.is_full() {
560                trace_log!("propagate_split {parent:?}:{idx} insert {right_ptr:p}");
561                // should insert next to left_ptr
562                parent.insert_no_split_with_idx(idx, promote_key, right_ptr);
563                return;
564            } else {
565                // Parent is full, try to borrow space from sibling through grand_parent
566                if let Some((mut grand, grand_idx)) = self.get_cache().peak_next() {
567                    // Try to borrow from left sibling of parent
568                    if grand_idx > 0 {
569                        let mut left_parent = grand.get_child_as_inter(grand_idx - 1);
570                        if !left_parent.is_full() {
571                            #[cfg(all(test, feature = "trace_log"))]
572                            {
573                                self.triggers |= TestFlag::InterMoveLeft as u32;
574                            }
575                            if idx == 0 {
576                                trace_log!(
577                                    "propagate_split rotate_left {grand:?}:{} first ->{left_parent:?} left {left_ptr:p} insert {idx} {right_ptr:p}",
578                                    grand_idx - 1
579                                );
580                                // special case: split from first child of parent
581                                let demote_key = grand.change_key(grand_idx - 1, promote_key);
582                                debug_assert_eq!(parent.get_child_ptr(0), left_ptr);
583                                unsafe { (*parent.child_ptr(0)) = right_ptr };
584                                left_parent.append(demote_key, left_ptr);
585                                #[cfg(all(test, feature = "trace_log"))]
586                                {
587                                    self.triggers |= TestFlag::InterMoveLeftFirst as u32;
588                                }
589                            } else {
590                                trace_log!(
591                                    "propagate_split insert_rotate_left {grand:?}:{grand_idx} -> {left_parent:?} insert {idx} {right_ptr:p}"
592                                );
593                                parent.insert_rotate_left(
594                                    &mut grand,
595                                    grand_idx,
596                                    &mut left_parent,
597                                    idx,
598                                    promote_key,
599                                    right_ptr,
600                                );
601                            }
602                            return;
603                        }
604                    }
605                    // Try to borrow from right sibling of parent
606                    if grand_idx < grand.key_count() {
607                        let mut right_parent = grand.get_child_as_inter(grand_idx + 1);
608                        if !right_parent.is_full() {
609                            #[cfg(all(test, feature = "trace_log"))]
610                            {
611                                self.triggers |= TestFlag::InterMoveRight as u32;
612                            }
613                            if idx == parent.key_count() {
614                                trace_log!(
615                                    "propagate_split rotate_right last {grand:?}:{grand_idx} -> {right_parent:?}:0 insert right {right_parent:?}:0 {right_ptr:p}"
616                                );
617                                // split from last child of parent
618                                let demote_key = grand.change_key(grand_idx, promote_key);
619                                right_parent.insert_at_front(right_ptr, demote_key);
620                                #[cfg(all(test, feature = "trace_log"))]
621                                {
622                                    self.triggers |= TestFlag::InterMoveRightLast as u32;
623                                }
624                            } else {
625                                trace_log!(
626                                    "propagate_split rotate_right {grand:?}:{grand_idx} -> {right_parent:?}:0 insert {parent:?}:{idx} {right_ptr:p}"
627                                );
628                                parent.rotate_right(&mut grand, grand_idx, &mut right_parent);
629                                parent.insert_no_split_with_idx(idx, promote_key, right_ptr);
630                            }
631                            return;
632                        }
633                    }
634                }
635                height += 1;
636
637                // Cannot borrow from siblings, need to split internal node
638                let (right, _promote_key) = parent.insert_split(promote_key, right_ptr);
639                promote_key = _promote_key;
640                right_ptr = right.get_ptr();
641                left_ptr = parent.get_ptr();
642                #[cfg(all(test, feature = "trace_log"))]
643                {
644                    self.triggers |= TestFlag::InterSplit as u32;
645                }
646                // Continue to next parent in cache (loop will pop next parent)
647            }
648        }
649        // No more parents in cache, create new root
650        let new_root = InterNode::<K, V>::new_root(height + 1, promote_key, left_ptr, right_ptr);
651        let _old_root = self.root.replace(Node::Inter(new_root)).expect("should have old root");
652        #[cfg(debug_assertions)]
653        {
654            match _old_root {
655                Node::Inter(node) => {
656                    debug_assert_eq!(height, node.height(), "old inter root at {height}");
657                    debug_assert_eq!(node.get_ptr(), left_ptr);
658                }
659                Node::Leaf(node) => {
660                    debug_assert_eq!(height, 0);
661                    debug_assert_eq!(node.get_ptr(), left_ptr);
662                }
663            }
664        }
665    }
666
667    /// Handle leaf node underflow by merging with sibling
668    /// Uses PathCache to accelerate parent lookup
669    /// Following the merge strategy from Designer Notes:
670    /// - Try merge with left sibling (if left + current <= cap)
671    /// - Try merge with right sibling (if current + right <= cap)
672    /// - Try 3-node merge (if left + current + right <= 2 * cap)
673    fn handle_leaf_underflow(&mut self, mut leaf: LeafNode<K, V>, merge: bool) {
674        debug_assert!(!self.get_root_unwrap().is_leaf());
675        let cur_count = leaf.key_count();
676        let cap = LeafNode::<K, V>::cap();
677        debug_assert!(cur_count <= cap >> 1);
678        let mut can_unlink: bool = false;
679        let (mut left_avail, mut right_avail) = (0, 0);
680        let mut merge_right = false;
681        if cur_count == 0 {
682            trace_log!("handle_leaf_underflow {leaf:?} unlink");
683            // if the right and left are full, or they not exist, can come to this
684            can_unlink = true;
685        }
686        if merge {
687            if !can_unlink && let Some(mut left_node) = leaf.get_left_node() {
688                let left_count = left_node.key_count();
689                if left_count + cur_count <= cap {
690                    trace_log!(
691                        "handle_leaf_underflow {leaf:?} merge left {left_node:?} {cur_count}"
692                    );
693                    leaf.copy_left(&mut left_node, cur_count);
694                    can_unlink = true;
695                    #[cfg(all(test, feature = "trace_log"))]
696                    {
697                        self.triggers |= TestFlag::LeafMergeLeft as u32;
698                    }
699                } else {
700                    left_avail = cap - left_count;
701                }
702            }
703            if !can_unlink && let Some(mut right_node) = leaf.get_right_node() {
704                let right_count = right_node.key_count();
705                if right_count + cur_count <= cap {
706                    trace_log!(
707                        "handle_leaf_underflow {leaf:?} merge right {right_node:?} {cur_count}"
708                    );
709                    leaf.copy_right::<false>(&mut right_node, 0, cur_count);
710                    can_unlink = true;
711                    merge_right = true;
712                    #[cfg(all(test, feature = "trace_log"))]
713                    {
714                        self.triggers |= TestFlag::LeafMergeRight as u32;
715                    }
716                } else {
717                    right_avail = cap - right_count;
718                }
719            }
720            // if we require left_avail + right_avail > cur_count, not possible to construct a 3-2
721            // merge, only either triggering merge left or merge right.
722            if !can_unlink
723                && left_avail > 0
724                && right_avail > 0
725                && left_avail + right_avail == cur_count
726            {
727                let mut left_node = leaf.get_left_node().unwrap();
728                let mut right_node = leaf.get_right_node().unwrap();
729                debug_assert!(left_avail < cur_count);
730                trace_log!("handle_leaf_underflow {leaf:?} merge left {left_node:?} {left_avail}");
731                leaf.copy_left(&mut left_node, left_avail);
732                trace_log!(
733                    "handle_leaf_underflow {leaf:?} merge right {right_node:?} {}",
734                    cur_count - left_avail
735                );
736                leaf.copy_right::<false>(&mut right_node, left_avail, cur_count - left_avail);
737                merge_right = true;
738                can_unlink = true;
739                #[cfg(all(test, feature = "trace_log"))]
740                {
741                    self.triggers |=
742                        TestFlag::LeafMergeLeft as u32 | TestFlag::LeafMergeRight as u32;
743                }
744            }
745        }
746        if !can_unlink {
747            return;
748        }
749        self.leaf_count -= 1;
750        let right_sep = if merge_right {
751            let right_node = leaf.get_right_node().unwrap();
752            Some(right_node.clone_first_key())
753        } else {
754            None
755        };
756        let no_right = leaf.unlink().is_null();
757        leaf.dealloc::<false>();
758        let (mut parent, mut idx) = self.get_cache().pop().unwrap();
759        trace_log!("handle_leaf_underflow pop parent {parent:?}:{idx}");
760        if parent.key_count() == 0 {
761            if let Some((grand, grand_idx)) = self.remove_only_child(parent) {
762                trace_log!("handle_leaf_underflow remove_only_child until {grand:?}:{grand_idx}");
763                parent = grand;
764                idx = grand_idx;
765            } else {
766                trace_log!("handle_leaf_underflow remove_only_child all");
767                return;
768            }
769        }
770        self.remove_child_from_inter(&mut parent, idx, right_sep, no_right);
771        if parent.key_count() <= 1 {
772            self.handle_inter_underflow(parent);
773        }
774    }
775
776    /// To simplify the logic, we perform delete first.
777    /// return the Some(node) when need to rebalance
778    #[inline]
779    fn remove_child_from_inter(
780        &mut self, node: &mut InterNode<K, V>, delete_idx: u32, right_sep: Option<K>,
781        _no_right: bool,
782    ) {
783        self.get_cache().assert_center();
784        debug_assert!(node.key_count() > 0, "{:?} {}", node, node.key_count());
785        if delete_idx == node.key_count() {
786            trace_log!("remove_child_from_inter {node:?}:{delete_idx} last");
787            #[cfg(all(test, feature = "trace_log"))]
788            {
789                self.triggers |= TestFlag::RemoveChildLast as u32;
790            }
791            // delete the last child of this node
792            node.remove_last_child();
793            if let Some(key) = right_sep
794                && let Some((grand_parent, grand_idx)) =
795                    self.get_cache().peak_ancenstor(|_node: &InterNode<K, V>, idx: u32| -> bool {
796                        _node.key_count() > idx
797                    })
798            {
799                #[cfg(all(test, feature = "trace_log"))]
800                {
801                    self.triggers |= TestFlag::UpdateSepKey as u32;
802                }
803                trace_log!("remove_child_from_inter change_key {grand_parent:?}:{grand_idx}");
804                // key idx = child idx - 1 , and + 1 for right node
805                grand_parent.change_key(grand_idx, key);
806            }
807        } else if delete_idx > 0 {
808            trace_log!("remove_child_from_inter {node:?}:{delete_idx} mid");
809            node.remove_mid_child(delete_idx);
810            #[cfg(all(test, feature = "trace_log"))]
811            {
812                self.triggers |= TestFlag::RemoveChildMid as u32;
813            }
814            // sep key of right node shift left
815            if let Some(key) = right_sep {
816                trace_log!("remove_child_from_inter change_key {node:?}:{}", delete_idx - 1);
817                node.change_key(delete_idx - 1, key);
818                #[cfg(all(test, feature = "trace_log"))]
819                {
820                    self.triggers |= TestFlag::UpdateSepKey as u32;
821                }
822            }
823        } else {
824            trace_log!("remove_child_from_inter {node:?}:{delete_idx} first");
825            // delete_idx is the first but not the last
826            let mut sep_key = node.remove_first_child();
827            #[cfg(all(test, feature = "trace_log"))]
828            {
829                self.triggers |= TestFlag::RemoveChildFirst as u32;
830            }
831            if let Some(key) = right_sep {
832                sep_key = key;
833            }
834            self.update_ancestor_sep_key::<false>(sep_key);
835        }
836    }
837
838    #[inline]
839    fn handle_inter_underflow(&mut self, mut node: InterNode<K, V>) {
840        let cap = InterNode::<K, V>::cap();
841        while node.key_count() <= InterNode::<K, V>::UNDERFLOW_CAP {
842            if node.key_count() == 0 {
843                let root_height = self.get_root_unwrap().height();
844                if node.height() == root_height
845                    || self
846                        .get_cache()
847                        .peak_ancenstor(|_node: &InterNode<K, V>, _idx: u32| -> bool {
848                            _node.key_count() > 0
849                        })
850                        .is_none()
851                {
852                    let root = unsafe { Node::from_header(*node.child_ptr(0)) };
853                    trace_log!("handle_inter_underflow downgrade root {root:?}");
854                    let _old_root = self.root.replace(root);
855                    debug_assert!(_old_root.is_some());
856
857                    while let Some((parent, _)) = self.get_cache().pop() {
858                        parent.dealloc::<false>();
859                    }
860                    node.dealloc::<false>(); // they all have no key
861                }
862                return;
863            } else {
864                if let Some((mut grand, grand_idx)) = self.get_cache().pop() {
865                    if grand_idx > 0 {
866                        let mut left = grand.get_child_as_inter(grand_idx - 1);
867                        // the sep key should pull down,  key+1 + key + 1 > cap + 1
868                        if left.key_count() + node.key_count() < cap {
869                            #[cfg(all(test, feature = "trace_log"))]
870                            {
871                                self.triggers |= TestFlag::InterMergeLeft as u32;
872                            }
873                            trace_log!(
874                                "handle_inter_underflow {node:?} merge left {left:?} parent {grand:?}:{grand_idx}"
875                            );
876                            left.merge(node, &mut grand, grand_idx);
877                            node = grand;
878                            continue;
879                        }
880                    }
881                    if grand_idx < grand.key_count() {
882                        let right = grand.get_child_as_inter(grand_idx + 1);
883                        // the sep key should pull down,  key+1 + key + 1 > cap + 1
884                        if right.key_count() + node.key_count() < cap {
885                            #[cfg(all(test, feature = "trace_log"))]
886                            {
887                                self.triggers |= TestFlag::InterMergeRight as u32;
888                            }
889                            trace_log!(
890                                "handle_inter_underflow {node:?} cap {cap} merge right {right:?} parent {grand:?}:{}",
891                                grand_idx + 1
892                            );
893                            node.merge(right, &mut grand, grand_idx + 1);
894                            node = grand;
895                            continue;
896                        }
897                    }
898                }
899                return;
900            }
901        }
902    }
903
904    #[inline]
905    fn remove_only_child(&mut self, node: InterNode<K, V>) -> Option<(InterNode<K, V>, u32)> {
906        debug_assert_eq!(node.key_count(), 0);
907        #[cfg(all(test, feature = "trace_log"))]
908        {
909            self.triggers |= TestFlag::RemoveOnlyChild as u32;
910        }
911        if let Some((parent, idx)) = self.get_cache().move_to_ancenstor(
912            |node: &InterNode<K, V>, _idx: u32| -> bool { node.key_count() != 0 },
913            InterNode::<K, V>::dealloc::<false>,
914        ) {
915            node.dealloc::<true>();
916            Some((parent, idx))
917        } else {
918            node.dealloc::<true>();
919            // we are empty, my ancestor are all empty and delete by move_to_ancenstor
920            self.root = None;
921            None
922        }
923    }
924
925    /// Dump the entire tree structure for debugging
926    #[cfg(all(test, feature = "std"))]
927    pub fn dump(&self)
928    where
929        K: Debug,
930        V: Debug,
931    {
932        print_log!("=== BTreeMap Dump ===");
933        print_log!("Length: {}", self.len());
934        if let Some(root) = &self.root {
935            self.dump_node(root, 0);
936        } else {
937            print_log!("(empty)");
938        }
939        print_log!("=====================");
940    }
941
942    #[cfg(all(test, feature = "std"))]
943    fn dump_node(&self, node: &Node<K, V>, depth: usize)
944    where
945        K: Debug,
946        V: Debug,
947    {
948        match node {
949            Node::Leaf(leaf) => {
950                print!("{:indent$}", "", indent = depth * 2);
951                print_log!("{}", leaf);
952            }
953            Node::Inter(inter) => {
954                print!("{:indent$}", "", indent = depth * 2);
955                print_log!("{}", inter);
956                // Dump children
957                let count = inter.key_count() as u32;
958                for i in 0..=count {
959                    unsafe {
960                        let child_ptr = *inter.child_ptr(i);
961                        if !child_ptr.is_null() {
962                            let child_node = if (*child_ptr).is_leaf() {
963                                Node::Leaf(LeafNode::<K, V>::from_header(child_ptr))
964                            } else {
965                                Node::Inter(InterNode::<K, V>::from_header(child_ptr))
966                            };
967                            self.dump_node(&child_node, depth + 1);
968                        }
969                    }
970                }
971            }
972        }
973    }
974
975    /// Validate the entire tree structure
976    /// Uses the same traversal logic as Drop to avoid recursion
977    pub fn validate(&self)
978    where
979        K: Debug,
980        V: Debug,
981    {
982        if self.root.is_none() {
983            assert_eq!(self.len, 0, "Empty tree should have len 0");
984            return;
985        }
986
987        let mut total_keys = 0usize;
988        let mut prev_leaf_max: Option<K> = None;
989
990        match &self.root {
991            Some(Node::Leaf(leaf)) => {
992                total_keys += leaf.validate(None, None);
993            }
994            Some(Node::Inter(inter)) => {
995                // Do not use btree internal PathCache (might distrupt test scenario)
996                let mut cache = PathCache::new();
997                let mut cur = inter.clone();
998                loop {
999                    cache.push(cur.clone(), 0);
1000                    cur.validate();
1001                    match cur.get_child(0) {
1002                        Node::Leaf(leaf) => {
1003                            // Validate first leaf with no min/max bounds from parent
1004                            let min_key: Option<K> = None;
1005                            let max_key = if inter.key_count() > 0 {
1006                                unsafe { Some((*inter.key_ptr(0)).assume_init_ref().clone()) }
1007                            } else {
1008                                None
1009                            };
1010                            total_keys += leaf.validate(min_key.as_ref(), max_key.as_ref());
1011                            if let Some(ref prev_max) = prev_leaf_max {
1012                                let first_key = unsafe { (*leaf.key_ptr(0)).assume_init_ref() };
1013                                assert!(
1014                                    prev_max < first_key,
1015                                    "{:?} Leaf keys not in order: prev max {:?} >= current min {:?}",
1016                                    leaf,
1017                                    prev_max,
1018                                    first_key
1019                                );
1020                            }
1021                            prev_leaf_max = unsafe {
1022                                Some(
1023                                    (*leaf.key_ptr(leaf.key_count() - 1)).assume_init_ref().clone(),
1024                                )
1025                            };
1026                            break;
1027                        }
1028                        Node::Inter(child_inter) => {
1029                            cur = child_inter;
1030                        }
1031                    }
1032                }
1033
1034                // Continue traversal like Drop does
1035                while let Some((parent, idx)) =
1036                    cache.move_right_and_pop_l1(dummy_post_callback::<K, V>)
1037                {
1038                    cache.push(parent.clone(), idx);
1039                    if let Node::Leaf(leaf) = parent.get_child(idx) {
1040                        // Calculate bounds for this leaf
1041                        let min_key = if idx > 0 {
1042                            unsafe { Some((*parent.key_ptr(idx - 1)).assume_init_ref().clone()) }
1043                        } else {
1044                            None
1045                        };
1046                        let max_key = if idx < parent.key_count() {
1047                            unsafe { Some((*parent.key_ptr(idx)).assume_init_ref().clone()) }
1048                        } else {
1049                            None
1050                        };
1051                        total_keys += leaf.validate(min_key.as_ref(), max_key.as_ref());
1052
1053                        // Check ordering with previous leaf
1054                        if let Some(ref prev_max) = prev_leaf_max {
1055                            let first_key = unsafe { (*leaf.key_ptr(0)).assume_init_ref() };
1056                            assert!(
1057                                prev_max < first_key,
1058                                "{:?} Leaf keys not in order: prev max {:?} >= current min {:?}",
1059                                leaf,
1060                                prev_max,
1061                                first_key
1062                            );
1063                        }
1064                        prev_leaf_max = unsafe {
1065                            Some((*leaf.key_ptr(leaf.key_count() - 1)).assume_init_ref().clone())
1066                        };
1067                    } else {
1068                        panic!("{parent:?} child {:?} is not leaf", parent.get_child(idx));
1069                    }
1070                }
1071            }
1072            None => unreachable!(),
1073        }
1074        assert_eq!(
1075            total_keys, self.len,
1076            "Total keys in tree ({}) doesn't match len ({})",
1077            total_keys, self.len
1078        );
1079    }
1080
1081    /// Returns the first key-value pair in the map
1082    /// Returns `None` if the map is empty
1083    #[inline]
1084    pub fn first_key_value(&self) -> Option<(&K, &V)> {
1085        let leaf = match &self.root {
1086            None => return None,
1087            Some(root) => root.find_first_leaf(None),
1088        };
1089        if leaf.key_count() == 0 {
1090            return None;
1091        }
1092        unsafe {
1093            let key = (*leaf.key_ptr(0)).assume_init_ref();
1094            let value = (*leaf.value_ptr(0)).assume_init_ref();
1095            Some((key, value))
1096        }
1097    }
1098
1099    /// Returns the last key-value pair in the map
1100    /// Returns `None` if the map is empty
1101    #[inline]
1102    pub fn last_key_value(&self) -> Option<(&K, &V)> {
1103        let leaf = match &self.root {
1104            None => return None,
1105            Some(root) => root.find_last_leaf(None),
1106        };
1107        let count = leaf.key_count();
1108        if count == 0 {
1109            return None;
1110        }
1111        unsafe {
1112            let last_idx = count - 1;
1113            let key = (*leaf.key_ptr(last_idx)).assume_init_ref();
1114            let value = (*leaf.value_ptr(last_idx)).assume_init_ref();
1115            Some((key, value))
1116        }
1117    }
1118
1119    /// Returns an entry to the first key in the map
1120    /// Returns `None` if the map is empty
1121    #[inline]
1122    pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
1123        let cache = self.get_cache();
1124        cache.clear();
1125        let leaf = match &self.root {
1126            None => return None,
1127            Some(root) => {
1128                // Populate cache with the path to first leaf
1129                root.find_first_leaf(Some(cache))
1130            }
1131        };
1132        if leaf.key_count() == 0 {
1133            return None;
1134        }
1135        Some(OccupiedEntry { tree: self, idx: 0, leaf })
1136    }
1137
1138    /// Returns an entry to the last key in the map
1139    /// Returns `None` if the map is empty
1140    #[inline]
1141    pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
1142        let cache = self.get_cache();
1143        cache.clear();
1144        let leaf = match &self.root {
1145            None => return None,
1146            Some(root) => {
1147                // Populate cache with the path to last leaf
1148                root.find_last_leaf(Some(cache))
1149            }
1150        };
1151        let count = leaf.key_count();
1152        if count == 0 {
1153            return None;
1154        }
1155        Some(OccupiedEntry { tree: self, idx: count - 1, leaf })
1156    }
1157
1158    /// Removes and returns the first key-value pair in the map
1159    /// Returns `None` if the map is empty
1160    #[inline]
1161    pub fn pop_first(&mut self) -> Option<(K, V)> {
1162        match self.first_entry() {
1163            Some(entry) => Some(entry.remove_entry()),
1164            _ => None,
1165        }
1166    }
1167
1168    /// Removes and returns the last key-value pair in the map
1169    /// Returns `None` if the map is empty
1170    #[inline]
1171    pub fn pop_last(&mut self) -> Option<(K, V)> {
1172        match self.last_entry() {
1173            Some(entry) => Some(entry.remove_entry()),
1174            _ => None,
1175        }
1176    }
1177
1178    /// Returns an iterator over the map's entries
1179    #[inline]
1180    pub fn iter(&self) -> Iter<'_, K, V> {
1181        Iter::new(self.find_first_and_last_leaf(), self.len)
1182    }
1183
1184    /// Returns a mutable iterator over the map's entries
1185    #[inline]
1186    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
1187        IterMut::new(self.find_first_and_last_leaf(), self.len)
1188    }
1189
1190    /// Return a consuming iterator in reversed order
1191    #[inline]
1192    pub fn into_iter_rev(self) -> IntoIter<K, V> {
1193        IntoIter::new(self, false)
1194    }
1195
1196    /// Returns an iterator over the map's keys
1197    #[inline]
1198    pub fn keys(&self) -> Keys<'_, K, V> {
1199        Keys::new(self.iter())
1200    }
1201
1202    /// Returns an iterator over the map's values
1203    #[inline]
1204    pub fn values(&self) -> Values<'_, K, V> {
1205        Values::new(self.iter())
1206    }
1207
1208    /// Returns a mutable iterator over the map's values
1209    #[inline]
1210    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
1211        ValuesMut::new(self.iter_mut())
1212    }
1213
1214    #[inline]
1215    fn find_first_and_last_leaf(&self) -> Option<(LeafNode<K, V>, LeafNode<K, V>)> {
1216        let root = self.root.as_ref()?;
1217        Some((root.find_first_leaf(None), root.find_last_leaf(None)))
1218    }
1219
1220    /// Internal helper to find range bounds
1221    /// Returns (front_leaf, front_idx, back_leaf, back_idx) where both leaves are Some or both are None
1222    #[inline]
1223    fn find_range_bounds<R>(&self, range: R) -> Option<RangeBase<'_, K, V>>
1224    where
1225        R: RangeBounds<K>,
1226    {
1227        let root = self.root.as_ref()?;
1228        let (front_leaf, front_idx) = root.find_leaf_with_bound(range.start_bound(), true);
1229        let (back_leaf, back_idx) = root.find_leaf_with_bound(range.end_bound(), false);
1230        Some(RangeBase::new(front_leaf, front_idx, back_leaf, back_idx))
1231    }
1232
1233    /// Returns an iterator over a sub-range of entries in the map
1234    #[inline]
1235    pub fn range<R>(&self, range: R) -> Range<'_, K, V>
1236    where
1237        R: RangeBounds<K>,
1238    {
1239        Range::new(self.find_range_bounds(range))
1240    }
1241
1242    /// Returns a mutable iterator over a sub-range of entries in the map
1243    #[inline]
1244    pub fn range_mut<R>(&mut self, range: R) -> RangeMut<'_, K, V>
1245    where
1246        R: RangeBounds<K>,
1247    {
1248        RangeMut::new(self.find_range_bounds(range))
1249    }
1250}
1251
1252impl<K: Ord + Clone + Sized, V: Sized> Default for BTreeMap<K, V> {
1253    fn default() -> Self {
1254        Self::new()
1255    }
1256}
1257
1258impl<K: Ord + Clone + Sized, V: Sized> Drop for BTreeMap<K, V> {
1259    fn drop(&mut self) {
1260        let mut cache = self.get_cache().take();
1261        let mut cur = match self.root.take() {
1262            None => return,
1263            Some(root) => root.find_first_leaf(Some(&mut cache)),
1264        };
1265        cur.dealloc::<true>();
1266        // To navigate to next leaf,
1267        // return None when reach the end
1268        while let Some((parent, idx)) = cache.move_right_and_pop_l1(InterNode::dealloc::<true>) {
1269            cache.push(parent.clone(), idx);
1270            cur = parent.get_child_as_leaf(idx);
1271            cur.dealloc::<true>();
1272        }
1273    }
1274}
1275
1276impl<K: Ord + Clone + Sized, V: Sized> IntoIterator for BTreeMap<K, V> {
1277    type Item = (K, V);
1278    type IntoIter = IntoIter<K, V>;
1279
1280    #[inline]
1281    fn into_iter(self) -> Self::IntoIter {
1282        IntoIter::new(self, true)
1283    }
1284}
1285
1286impl<'a, K: Ord + Clone + Sized, V: Sized> IntoIterator for &'a BTreeMap<K, V> {
1287    type Item = (&'a K, &'a V);
1288    type IntoIter = Iter<'a, K, V>;
1289
1290    #[inline]
1291    fn into_iter(self) -> Self::IntoIter {
1292        self.iter()
1293    }
1294}
1295
1296impl<'a, K: Ord + Clone + Sized, V: Sized> IntoIterator for &'a mut BTreeMap<K, V> {
1297    type Item = (&'a K, &'a mut V);
1298    type IntoIter = IterMut<'a, K, V>;
1299
1300    #[inline]
1301    fn into_iter(self) -> Self::IntoIter {
1302        self.iter_mut()
1303    }
1304}