Skip to main content

alloc/collections/btree/
fix.rs

1use core::alloc::AllocatorClone;
2
3use super::map::MIN_LEN;
4use super::node::ForceResult::*;
5use super::node::LeftOrRight::*;
6use super::node::{Handle, NodeRef, Root, marker};
7
8impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
9    /// Stocks up a possibly underfull node by merging with or stealing from a
10    /// sibling. If successful but at the cost of shrinking the parent node,
11    /// returns that shrunk parent node. Returns an `Err` if the node is
12    /// an empty root.
13    fn fix_node_through_parent<A: AllocatorClone>(
14        self,
15        alloc: A,
16    ) -> Result<Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>>, Self> {
17        let len = self.len();
18        if len >= MIN_LEN {
19            Ok(None)
20        } else {
21            match self.choose_parent_kv() {
22                Ok(Left(mut left_parent_kv)) => {
23                    if left_parent_kv.can_merge() {
24                        let parent = left_parent_kv.merge_tracking_parent(alloc);
25                        Ok(Some(parent))
26                    } else {
27                        left_parent_kv.bulk_steal_left(MIN_LEN - len);
28                        Ok(None)
29                    }
30                }
31                Ok(Right(mut right_parent_kv)) => {
32                    if right_parent_kv.can_merge() {
33                        let parent = right_parent_kv.merge_tracking_parent(alloc);
34                        Ok(Some(parent))
35                    } else {
36                        right_parent_kv.bulk_steal_right(MIN_LEN - len);
37                        Ok(None)
38                    }
39                }
40                Err(root) => {
41                    if len > 0 {
42                        Ok(None)
43                    } else {
44                        Err(root)
45                    }
46                }
47            }
48        }
49    }
50}
51
52impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
53    /// Stocks up a possibly underfull node, and if that causes its parent node
54    /// to shrink, stocks up the parent, recursively.
55    /// Returns `true` if it fixed the tree, `false` if it couldn't because the
56    /// root node became empty.
57    ///
58    /// This method does not expect ancestors to already be underfull upon entry
59    /// and panics if it encounters an empty ancestor.
60    pub(super) fn fix_node_and_affected_ancestors<A: AllocatorClone>(mut self, alloc: A) -> bool {
61        loop {
62            match self.fix_node_through_parent(alloc.clone()) {
63                Ok(Some(parent)) => self = parent.forget_type(),
64                Ok(None) => return true,
65                Err(_) => return false,
66            }
67        }
68    }
69}
70
71impl<K, V> Root<K, V> {
72    /// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
73    pub(super) fn fix_top<A: AllocatorClone>(&mut self, alloc: A) {
74        while self.height() > 0 && self.len() == 0 {
75            self.pop_internal_level(alloc.clone());
76        }
77    }
78
79    /// Stocks up or merge away any underfull nodes on the right border of the
80    /// tree. The other nodes, those that are not the root nor a rightmost edge,
81    /// must already have at least MIN_LEN elements.
82    pub(super) fn fix_right_border<A: AllocatorClone>(&mut self, alloc: A) {
83        self.fix_top(alloc.clone());
84        if self.len() > 0 {
85            self.borrow_mut().last_kv().fix_right_border_of_right_edge(alloc.clone());
86            self.fix_top(alloc);
87        }
88    }
89
90    /// The symmetric clone of `fix_right_border`.
91    pub(super) fn fix_left_border<A: AllocatorClone>(&mut self, alloc: A) {
92        self.fix_top(alloc.clone());
93        if self.len() > 0 {
94            self.borrow_mut().first_kv().fix_left_border_of_left_edge(alloc.clone());
95            self.fix_top(alloc);
96        }
97    }
98
99    /// Stocks up any underfull nodes on the right border of the tree.
100    /// The other nodes, those that are neither the root nor a rightmost edge,
101    /// must be prepared to have up to MIN_LEN elements stolen.
102    pub(super) fn fix_right_border_of_plentiful(&mut self) {
103        let mut cur_node = self.borrow_mut();
104        while let Internal(internal) = cur_node.force() {
105            // Check if rightmost child is underfull.
106            let mut last_kv = internal.last_kv().consider_for_balancing();
107            if true {
    if !(last_kv.left_child_len() >= MIN_LEN * 2) {
        ::core::panicking::panic("assertion failed: last_kv.left_child_len() >= MIN_LEN * 2")
    };
};debug_assert!(last_kv.left_child_len() >= MIN_LEN * 2);
108            let right_child_len = last_kv.right_child_len();
109            if right_child_len < MIN_LEN {
110                // We need to steal.
111                last_kv.bulk_steal_left(MIN_LEN - right_child_len);
112            }
113
114            // Go further down.
115            cur_node = last_kv.into_right_child();
116        }
117    }
118}
119
120impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
121    fn fix_left_border_of_left_edge<A: AllocatorClone>(mut self, alloc: A) {
122        while let Internal(internal_kv) = self.force() {
123            self = internal_kv.fix_left_child(alloc.clone()).first_kv();
124            if true {
    if !(self.reborrow().into_node().len() > MIN_LEN) {
        ::core::panicking::panic("assertion failed: self.reborrow().into_node().len() > MIN_LEN")
    };
};debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
125        }
126    }
127
128    fn fix_right_border_of_right_edge<A: AllocatorClone>(mut self, alloc: A) {
129        while let Internal(internal_kv) = self.force() {
130            self = internal_kv.fix_right_child(alloc.clone()).last_kv();
131            if true {
    if !(self.reborrow().into_node().len() > MIN_LEN) {
        ::core::panicking::panic("assertion failed: self.reborrow().into_node().len() > MIN_LEN")
    };
};debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
132        }
133    }
134}
135
136impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::KV> {
137    /// Stocks up the left child, assuming the right child isn't underfull, and
138    /// provisions an extra element to allow merging its children in turn
139    /// without becoming underfull.
140    /// Returns the left child.
141    fn fix_left_child<A: AllocatorClone>(
142        self,
143        alloc: A,
144    ) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
145        let mut internal_kv = self.consider_for_balancing();
146        let left_len = internal_kv.left_child_len();
147        if true {
    if !(internal_kv.right_child_len() >= MIN_LEN) {
        ::core::panicking::panic("assertion failed: internal_kv.right_child_len() >= MIN_LEN")
    };
};debug_assert!(internal_kv.right_child_len() >= MIN_LEN);
148        if internal_kv.can_merge() {
149            internal_kv.merge_tracking_child(alloc)
150        } else {
151            // `MIN_LEN + 1` to avoid readjust if merge happens on the next level.
152            let count = (MIN_LEN + 1).saturating_sub(left_len);
153            if count > 0 {
154                internal_kv.bulk_steal_right(count);
155            }
156            internal_kv.into_left_child()
157        }
158    }
159
160    /// Stocks up the right child, assuming the left child isn't underfull, and
161    /// provisions an extra element to allow merging its children in turn
162    /// without becoming underfull.
163    /// Returns wherever the right child ended up.
164    fn fix_right_child<A: AllocatorClone>(
165        self,
166        alloc: A,
167    ) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
168        let mut internal_kv = self.consider_for_balancing();
169        let right_len = internal_kv.right_child_len();
170        if true {
    if !(internal_kv.left_child_len() >= MIN_LEN) {
        ::core::panicking::panic("assertion failed: internal_kv.left_child_len() >= MIN_LEN")
    };
};debug_assert!(internal_kv.left_child_len() >= MIN_LEN);
171        if internal_kv.can_merge() {
172            internal_kv.merge_tracking_child(alloc)
173        } else {
174            // `MIN_LEN + 1` to avoid readjust if merge happens on the next level.
175            let count = (MIN_LEN + 1).saturating_sub(right_len);
176            if count > 0 {
177                internal_kv.bulk_steal_left(count);
178            }
179            internal_kv.into_right_child()
180        }
181    }
182}