| 1 | use core::alloc::Allocator; |
| 2 | |
| 3 | use super::map::MIN_LEN; |
| 4 | use super::node::ForceResult::*; |
| 5 | use super::node::LeftOrRight::*; |
| 6 | use super::node::{Handle, NodeRef, Root, marker}; |
| 7 | |
| 8 | impl<'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: Allocator + Clone>( |
| 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 | |
| 52 | impl<'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: Allocator + Clone>( |
| 61 | mut self, |
| 62 | alloc: A, |
| 63 | ) -> bool { |
| 64 | loop { |
| 65 | match self.fix_node_through_parent(alloc.clone()) { |
| 66 | Ok(Some(parent: NodeRef, K, V, Internal>)) => self = parent.forget_type(), |
| 67 | Ok(None) => return true, |
| 68 | Err(_) => return false, |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | impl<K, V> Root<K, V> { |
| 75 | /// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty. |
| 76 | pub(super) fn fix_top<A: Allocator + Clone>(&mut self, alloc: A) { |
| 77 | while self.height() > 0 && self.len() == 0 { |
| 78 | self.pop_internal_level(alloc.clone()); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | /// Stocks up or merge away any underfull nodes on the right border of the |
| 83 | /// tree. The other nodes, those that are not the root nor a rightmost edge, |
| 84 | /// must already have at least MIN_LEN elements. |
| 85 | pub(super) fn fix_right_border<A: Allocator + Clone>(&mut self, alloc: A) { |
| 86 | self.fix_top(alloc.clone()); |
| 87 | if self.len() > 0 { |
| 88 | self.borrow_mut().last_kv().fix_right_border_of_right_edge(alloc.clone()); |
| 89 | self.fix_top(alloc); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | /// The symmetric clone of `fix_right_border`. |
| 94 | pub(super) fn fix_left_border<A: Allocator + Clone>(&mut self, alloc: A) { |
| 95 | self.fix_top(alloc.clone()); |
| 96 | if self.len() > 0 { |
| 97 | self.borrow_mut().first_kv().fix_left_border_of_left_edge(alloc.clone()); |
| 98 | self.fix_top(alloc); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | /// Stocks up any underfull nodes on the right border of the tree. |
| 103 | /// The other nodes, those that are neither the root nor a rightmost edge, |
| 104 | /// must be prepared to have up to MIN_LEN elements stolen. |
| 105 | pub(super) fn fix_right_border_of_plentiful(&mut self) { |
| 106 | let mut cur_node = self.borrow_mut(); |
| 107 | while let Internal(internal) = cur_node.force() { |
| 108 | // Check if rightmost child is underfull. |
| 109 | let mut last_kv = internal.last_kv().consider_for_balancing(); |
| 110 | debug_assert!(last_kv.left_child_len() >= MIN_LEN * 2); |
| 111 | let right_child_len = last_kv.right_child_len(); |
| 112 | if right_child_len < MIN_LEN { |
| 113 | // We need to steal. |
| 114 | last_kv.bulk_steal_left(MIN_LEN - right_child_len); |
| 115 | } |
| 116 | |
| 117 | // Go further down. |
| 118 | cur_node = last_kv.into_right_child(); |
| 119 | } |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> { |
| 124 | fn fix_left_border_of_left_edge<A: Allocator + Clone>(mut self, alloc: A) { |
| 125 | while let Internal(internal_kv: Handle, K, …, …>, …>) = self.force() { |
| 126 | self = internal_kv.fix_left_child(alloc.clone()).first_kv(); |
| 127 | debug_assert!(self.reborrow().into_node().len() > MIN_LEN); |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | fn fix_right_border_of_right_edge<A: Allocator + Clone>(mut self, alloc: A) { |
| 132 | while let Internal(internal_kv: Handle, K, …, …>, …>) = self.force() { |
| 133 | self = internal_kv.fix_right_child(alloc.clone()).last_kv(); |
| 134 | debug_assert!(self.reborrow().into_node().len() > MIN_LEN); |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::KV> { |
| 140 | /// Stocks up the left child, assuming the right child isn't underfull, and |
| 141 | /// provisions an extra element to allow merging its children in turn |
| 142 | /// without becoming underfull. |
| 143 | /// Returns the left child. |
| 144 | fn fix_left_child<A: Allocator + Clone>( |
| 145 | self, |
| 146 | alloc: A, |
| 147 | ) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { |
| 148 | let mut internal_kv = self.consider_for_balancing(); |
| 149 | let left_len = internal_kv.left_child_len(); |
| 150 | debug_assert!(internal_kv.right_child_len() >= MIN_LEN); |
| 151 | if internal_kv.can_merge() { |
| 152 | internal_kv.merge_tracking_child(alloc) |
| 153 | } else { |
| 154 | // `MIN_LEN + 1` to avoid readjust if merge happens on the next level. |
| 155 | let count = (MIN_LEN + 1).saturating_sub(left_len); |
| 156 | if count > 0 { |
| 157 | internal_kv.bulk_steal_right(count); |
| 158 | } |
| 159 | internal_kv.into_left_child() |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | /// Stocks up the right child, assuming the left child isn't underfull, and |
| 164 | /// provisions an extra element to allow merging its children in turn |
| 165 | /// without becoming underfull. |
| 166 | /// Returns wherever the right child ended up. |
| 167 | fn fix_right_child<A: Allocator + Clone>( |
| 168 | self, |
| 169 | alloc: A, |
| 170 | ) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { |
| 171 | let mut internal_kv = self.consider_for_balancing(); |
| 172 | let right_len = internal_kv.right_child_len(); |
| 173 | debug_assert!(internal_kv.left_child_len() >= MIN_LEN); |
| 174 | if internal_kv.can_merge() { |
| 175 | internal_kv.merge_tracking_child(alloc) |
| 176 | } else { |
| 177 | // `MIN_LEN + 1` to avoid readjust if merge happens on the next level. |
| 178 | let count = (MIN_LEN + 1).saturating_sub(right_len); |
| 179 | if count > 0 { |
| 180 | internal_kv.bulk_steal_left(count); |
| 181 | } |
| 182 | internal_kv.into_right_child() |
| 183 | } |
| 184 | } |
| 185 | } |
| 186 | |