/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cranelift-bforest-0.128.3/src/node.rs
Line | Count | Source |
1 | | //! B+-tree nodes. |
2 | | |
3 | | use super::{Forest, INNER_SIZE, Node, SetValue, slice_insert, slice_shift}; |
4 | | use core::borrow::{Borrow, BorrowMut}; |
5 | | use core::fmt; |
6 | | |
7 | | /// B+-tree node. |
8 | | /// |
9 | | /// A B+-tree has different node types for inner nodes and leaf nodes. Inner nodes contain M node |
10 | | /// references and M-1 keys while leaf nodes contain N keys and values. Values for M and N are |
11 | | /// chosen such that a node is exactly 64 bytes (a cache line) when keys and values are 32 bits |
12 | | /// each. |
13 | | /// |
14 | | /// An inner node contains at least M/2 node references unless it is the right-most node at its |
15 | | /// level. A leaf node contains at least N/2 keys unless it is the right-most leaf. |
16 | | pub(super) enum NodeData<F: Forest> { |
17 | | Inner { |
18 | | /// The number of keys in this node. |
19 | | /// The number of node references is always one more. |
20 | | size: u8, |
21 | | |
22 | | /// Keys discriminating sub-trees. |
23 | | /// |
24 | | /// The key in `keys[i]` is greater than all keys in `tree[i]` and less than or equal to |
25 | | /// all keys in `tree[i+1]`. |
26 | | keys: [F::Key; INNER_SIZE - 1], |
27 | | |
28 | | /// Sub-trees. |
29 | | tree: [Node; INNER_SIZE], |
30 | | }, |
31 | | Leaf { |
32 | | /// Number of key-value pairs in this node. |
33 | | size: u8, |
34 | | |
35 | | // Key array. |
36 | | keys: F::LeafKeys, |
37 | | |
38 | | // Value array. |
39 | | vals: F::LeafValues, |
40 | | }, |
41 | | /// An unused node on the free list. |
42 | | Free { next: Option<Node> }, |
43 | | } |
44 | | |
45 | | // Implement `Clone` and `Copy` manually, because deriving them would also require `Forest` to |
46 | | // implement `Clone`. |
47 | | impl<F: Forest> Copy for NodeData<F> {} |
48 | | impl<F: Forest> Clone for NodeData<F> { |
49 | 0 | fn clone(&self) -> Self { |
50 | 0 | *self |
51 | 0 | } |
52 | | } |
53 | | |
54 | | impl<F: Forest> NodeData<F> { |
55 | | /// Is this a free/unused node? |
56 | 0 | pub fn is_free(&self) -> bool { |
57 | 0 | match *self { |
58 | 0 | Self::Free { .. } => true, |
59 | 0 | _ => false, |
60 | | } |
61 | 0 | } |
62 | | |
63 | | /// Get the number of entries in this node. |
64 | | /// |
65 | | /// This is the number of outgoing edges in an inner node, or the number of key-value pairs in |
66 | | /// a leaf node. |
67 | 70.6k | pub fn entries(&self) -> usize { |
68 | 70.6k | match *self { |
69 | 1.89k | Self::Inner { size, .. } => usize::from(size) + 1, |
70 | 68.7k | Self::Leaf { size, .. } => usize::from(size), |
71 | 0 | Self::Free { .. } => panic!("freed node"), |
72 | | } |
73 | 70.6k | } Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::entries Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::entries <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::entries Line | Count | Source | 67 | 70.6k | pub fn entries(&self) -> usize { | 68 | 70.6k | match *self { | 69 | 1.89k | Self::Inner { size, .. } => usize::from(size) + 1, | 70 | 68.7k | Self::Leaf { size, .. } => usize::from(size), | 71 | 0 | Self::Free { .. } => panic!("freed node"), | 72 | | } | 73 | 70.6k | } |
|
74 | | |
75 | | /// Create an inner node with a single key and two sub-trees. |
76 | 6.70k | pub fn inner(left: Node, key: F::Key, right: Node) -> Self { |
77 | | // Splat the key and right node to the whole array. |
78 | | // Saves us from inventing a default/reserved value. |
79 | 6.70k | let mut tree = [right; INNER_SIZE]; |
80 | 6.70k | tree[0] = left; |
81 | 6.70k | Self::Inner { |
82 | 6.70k | size: 1, |
83 | 6.70k | keys: [key; INNER_SIZE - 1], |
84 | 6.70k | tree, |
85 | 6.70k | } |
86 | 6.70k | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::inner Line | Count | Source | 76 | 476 | pub fn inner(left: Node, key: F::Key, right: Node) -> Self { | 77 | | // Splat the key and right node to the whole array. | 78 | | // Saves us from inventing a default/reserved value. | 79 | 476 | let mut tree = [right; INNER_SIZE]; | 80 | 476 | tree[0] = left; | 81 | 476 | Self::Inner { | 82 | 476 | size: 1, | 83 | 476 | keys: [key; INNER_SIZE - 1], | 84 | 476 | tree, | 85 | 476 | } | 86 | 476 | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::inner Line | Count | Source | 76 | 28 | pub fn inner(left: Node, key: F::Key, right: Node) -> Self { | 77 | | // Splat the key and right node to the whole array. | 78 | | // Saves us from inventing a default/reserved value. | 79 | 28 | let mut tree = [right; INNER_SIZE]; | 80 | 28 | tree[0] = left; | 81 | 28 | Self::Inner { | 82 | 28 | size: 1, | 83 | 28 | keys: [key; INNER_SIZE - 1], | 84 | 28 | tree, | 85 | 28 | } | 86 | 28 | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::inner <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::inner Line | Count | Source | 76 | 5.53k | pub fn inner(left: Node, key: F::Key, right: Node) -> Self { | 77 | | // Splat the key and right node to the whole array. | 78 | | // Saves us from inventing a default/reserved value. | 79 | 5.53k | let mut tree = [right; INNER_SIZE]; | 80 | 5.53k | tree[0] = left; | 81 | 5.53k | Self::Inner { | 82 | 5.53k | size: 1, | 83 | 5.53k | keys: [key; INNER_SIZE - 1], | 84 | 5.53k | tree, | 85 | 5.53k | } | 86 | 5.53k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::inner Line | Count | Source | 76 | 658 | pub fn inner(left: Node, key: F::Key, right: Node) -> Self { | 77 | | // Splat the key and right node to the whole array. | 78 | | // Saves us from inventing a default/reserved value. | 79 | 658 | let mut tree = [right; INNER_SIZE]; | 80 | 658 | tree[0] = left; | 81 | 658 | Self::Inner { | 82 | 658 | size: 1, | 83 | 658 | keys: [key; INNER_SIZE - 1], | 84 | 658 | tree, | 85 | 658 | } | 86 | 658 | } |
|
87 | | |
88 | | /// Create a leaf node with a single key-value pair. |
89 | 23.5M | pub fn leaf(key: F::Key, value: F::Value) -> Self { |
90 | 23.5M | Self::Leaf { |
91 | 23.5M | size: 1, |
92 | 23.5M | keys: F::splat_key(key), |
93 | 23.5M | vals: F::splat_value(value), |
94 | 23.5M | } |
95 | 23.5M | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf Line | Count | Source | 89 | 876k | pub fn leaf(key: F::Key, value: F::Value) -> Self { | 90 | 876k | Self::Leaf { | 91 | 876k | size: 1, | 92 | 876k | keys: F::splat_key(key), | 93 | 876k | vals: F::splat_value(value), | 94 | 876k | } | 95 | 876k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::leaf Line | Count | Source | 89 | 879k | pub fn leaf(key: F::Key, value: F::Value) -> Self { | 90 | 879k | Self::Leaf { | 91 | 879k | size: 1, | 92 | 879k | keys: F::splat_key(key), | 93 | 879k | vals: F::splat_value(value), | 94 | 879k | } | 95 | 879k | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::leaf <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf Line | Count | Source | 89 | 11.2M | pub fn leaf(key: F::Key, value: F::Value) -> Self { | 90 | 11.2M | Self::Leaf { | 91 | 11.2M | size: 1, | 92 | 11.2M | keys: F::splat_key(key), | 93 | 11.2M | vals: F::splat_value(value), | 94 | 11.2M | } | 95 | 11.2M | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::leaf Line | Count | Source | 89 | 10.5M | pub fn leaf(key: F::Key, value: F::Value) -> Self { | 90 | 10.5M | Self::Leaf { | 91 | 10.5M | size: 1, | 92 | 10.5M | keys: F::splat_key(key), | 93 | 10.5M | vals: F::splat_value(value), | 94 | 10.5M | } | 95 | 10.5M | } |
|
96 | | |
97 | | /// Unwrap an inner node into two slices (keys, trees). |
98 | 621k | pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) { |
99 | 621k | match *self { |
100 | | Self::Inner { |
101 | 621k | size, |
102 | 621k | ref keys, |
103 | 621k | ref tree, |
104 | | } => { |
105 | 621k | let size = usize::from(size); |
106 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in |
107 | | // range. |
108 | 621k | (&keys[0..size], &tree[0..=size]) |
109 | | } |
110 | 0 | _ => panic!("Expected inner node"), |
111 | | } |
112 | 621k | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_inner Line | Count | Source | 98 | 11.2k | pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) { | 99 | 11.2k | match *self { | 100 | | Self::Inner { | 101 | 11.2k | size, | 102 | 11.2k | ref keys, | 103 | 11.2k | ref tree, | 104 | | } => { | 105 | 11.2k | let size = usize::from(size); | 106 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 107 | | // range. | 108 | 11.2k | (&keys[0..size], &tree[0..=size]) | 109 | | } | 110 | 0 | _ => panic!("Expected inner node"), | 111 | | } | 112 | 11.2k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::unwrap_inner Line | Count | Source | 98 | 72 | pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) { | 99 | 72 | match *self { | 100 | | Self::Inner { | 101 | 72 | size, | 102 | 72 | ref keys, | 103 | 72 | ref tree, | 104 | | } => { | 105 | 72 | let size = usize::from(size); | 106 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 107 | | // range. | 108 | 72 | (&keys[0..size], &tree[0..=size]) | 109 | | } | 110 | 0 | _ => panic!("Expected inner node"), | 111 | | } | 112 | 72 | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::unwrap_inner <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_inner Line | Count | Source | 98 | 608k | pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) { | 99 | 608k | match *self { | 100 | | Self::Inner { | 101 | 608k | size, | 102 | 608k | ref keys, | 103 | 608k | ref tree, | 104 | | } => { | 105 | 608k | let size = usize::from(size); | 106 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 107 | | // range. | 108 | 608k | (&keys[0..size], &tree[0..=size]) | 109 | | } | 110 | 0 | _ => panic!("Expected inner node"), | 111 | | } | 112 | 608k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::unwrap_inner Line | Count | Source | 98 | 2.55k | pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) { | 99 | 2.55k | match *self { | 100 | | Self::Inner { | 101 | 2.55k | size, | 102 | 2.55k | ref keys, | 103 | 2.55k | ref tree, | 104 | | } => { | 105 | 2.55k | let size = usize::from(size); | 106 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 107 | | // range. | 108 | 2.55k | (&keys[0..size], &tree[0..=size]) | 109 | | } | 110 | 0 | _ => panic!("Expected inner node"), | 111 | | } | 112 | 2.55k | } |
|
113 | | |
114 | | /// Unwrap a leaf node into two slices (keys, values) of the same length. |
115 | 40.4M | pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) { |
116 | 40.4M | match *self { |
117 | | Self::Leaf { |
118 | 40.4M | size, |
119 | 40.4M | ref keys, |
120 | 40.4M | ref vals, |
121 | | } => { |
122 | 40.4M | let size = usize::from(size); |
123 | 40.4M | let keys = keys.borrow(); |
124 | 40.4M | let vals = vals.borrow(); |
125 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in |
126 | | // range. |
127 | 40.4M | (&keys[0..size], &vals[0..size]) |
128 | | } |
129 | 0 | _ => panic!("Expected leaf node"), |
130 | | } |
131 | 40.4M | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_leaf Line | Count | Source | 115 | 2.23M | pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) { | 116 | 2.23M | match *self { | 117 | | Self::Leaf { | 118 | 2.23M | size, | 119 | 2.23M | ref keys, | 120 | 2.23M | ref vals, | 121 | | } => { | 122 | 2.23M | let size = usize::from(size); | 123 | 2.23M | let keys = keys.borrow(); | 124 | 2.23M | let vals = vals.borrow(); | 125 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 126 | | // range. | 127 | 2.23M | (&keys[0..size], &vals[0..size]) | 128 | | } | 129 | 0 | _ => panic!("Expected leaf node"), | 130 | | } | 131 | 2.23M | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::unwrap_leaf Line | Count | Source | 115 | 950k | pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) { | 116 | 950k | match *self { | 117 | | Self::Leaf { | 118 | 950k | size, | 119 | 950k | ref keys, | 120 | 950k | ref vals, | 121 | | } => { | 122 | 950k | let size = usize::from(size); | 123 | 950k | let keys = keys.borrow(); | 124 | 950k | let vals = vals.borrow(); | 125 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 126 | | // range. | 127 | 950k | (&keys[0..size], &vals[0..size]) | 128 | | } | 129 | 0 | _ => panic!("Expected leaf node"), | 130 | | } | 131 | 950k | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::unwrap_leaf <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_leaf Line | Count | Source | 115 | 26.6M | pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) { | 116 | 26.6M | match *self { | 117 | | Self::Leaf { | 118 | 26.6M | size, | 119 | 26.6M | ref keys, | 120 | 26.6M | ref vals, | 121 | | } => { | 122 | 26.6M | let size = usize::from(size); | 123 | 26.6M | let keys = keys.borrow(); | 124 | 26.6M | let vals = vals.borrow(); | 125 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 126 | | // range. | 127 | 26.6M | (&keys[0..size], &vals[0..size]) | 128 | | } | 129 | 0 | _ => panic!("Expected leaf node"), | 130 | | } | 131 | 26.6M | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::unwrap_leaf Line | Count | Source | 115 | 10.5M | pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) { | 116 | 10.5M | match *self { | 117 | | Self::Leaf { | 118 | 10.5M | size, | 119 | 10.5M | ref keys, | 120 | 10.5M | ref vals, | 121 | | } => { | 122 | 10.5M | let size = usize::from(size); | 123 | 10.5M | let keys = keys.borrow(); | 124 | 10.5M | let vals = vals.borrow(); | 125 | | // TODO: We could probably use `get_unchecked()` here since `size` is always in | 126 | | // range. | 127 | 10.5M | (&keys[0..size], &vals[0..size]) | 128 | | } | 129 | 0 | _ => panic!("Expected leaf node"), | 130 | | } | 131 | 10.5M | } |
|
132 | | |
133 | | /// Unwrap a mutable leaf node into two slices (keys, values) of the same length. |
134 | 2.40M | pub fn unwrap_leaf_mut(&mut self) -> (&mut [F::Key], &mut [F::Value]) { |
135 | 2.40M | match *self { |
136 | | Self::Leaf { |
137 | 2.40M | size, |
138 | 2.40M | ref mut keys, |
139 | 2.40M | ref mut vals, |
140 | | } => { |
141 | 2.40M | let size = usize::from(size); |
142 | 2.40M | let keys = keys.borrow_mut(); |
143 | 2.40M | let vals = vals.borrow_mut(); |
144 | | // TODO: We could probably use `get_unchecked_mut()` here since `size` is always in |
145 | | // range. |
146 | 2.40M | (&mut keys[0..size], &mut vals[0..size]) |
147 | | } |
148 | 0 | _ => panic!("Expected leaf node"), |
149 | | } |
150 | 2.40M | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_leaf_mut Line | Count | Source | 134 | 742 | pub fn unwrap_leaf_mut(&mut self) -> (&mut [F::Key], &mut [F::Value]) { | 135 | 742 | match *self { | 136 | | Self::Leaf { | 137 | 742 | size, | 138 | 742 | ref mut keys, | 139 | 742 | ref mut vals, | 140 | | } => { | 141 | 742 | let size = usize::from(size); | 142 | 742 | let keys = keys.borrow_mut(); | 143 | 742 | let vals = vals.borrow_mut(); | 144 | | // TODO: We could probably use `get_unchecked_mut()` here since `size` is always in | 145 | | // range. | 146 | 742 | (&mut keys[0..size], &mut vals[0..size]) | 147 | | } | 148 | 0 | _ => panic!("Expected leaf node"), | 149 | | } | 150 | 742 | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::unwrap_leaf_mut <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_leaf_mut Line | Count | Source | 134 | 2.40M | pub fn unwrap_leaf_mut(&mut self) -> (&mut [F::Key], &mut [F::Value]) { | 135 | 2.40M | match *self { | 136 | | Self::Leaf { | 137 | 2.40M | size, | 138 | 2.40M | ref mut keys, | 139 | 2.40M | ref mut vals, | 140 | | } => { | 141 | 2.40M | let size = usize::from(size); | 142 | 2.40M | let keys = keys.borrow_mut(); | 143 | 2.40M | let vals = vals.borrow_mut(); | 144 | | // TODO: We could probably use `get_unchecked_mut()` here since `size` is always in | 145 | | // range. | 146 | 2.40M | (&mut keys[0..size], &mut vals[0..size]) | 147 | | } | 148 | 0 | _ => panic!("Expected leaf node"), | 149 | | } | 150 | 2.40M | } |
|
151 | | |
152 | | /// Get the critical key for a leaf node. |
153 | | /// This is simply the first key. |
154 | 54 | pub fn leaf_crit_key(&self) -> F::Key { |
155 | 54 | match *self { |
156 | 54 | Self::Leaf { size, ref keys, .. } => { |
157 | 54 | debug_assert!(size > 0, "Empty leaf node"); |
158 | 54 | keys.borrow()[0] |
159 | | } |
160 | 0 | _ => panic!("Expected leaf node"), |
161 | | } |
162 | 54 | } Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf_crit_key Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::leaf_crit_key <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf_crit_key Line | Count | Source | 154 | 54 | pub fn leaf_crit_key(&self) -> F::Key { | 155 | 54 | match *self { | 156 | 54 | Self::Leaf { size, ref keys, .. } => { | 157 | 54 | debug_assert!(size > 0, "Empty leaf node"); | 158 | 54 | keys.borrow()[0] | 159 | | } | 160 | 0 | _ => panic!("Expected leaf node"), | 161 | | } | 162 | 54 | } |
|
163 | | |
164 | | /// Try to insert `(key, node)` at key-position `index` in an inner node. |
165 | | /// This means that `key` is inserted at `keys[i]` and `node` is inserted at `tree[i + 1]`. |
166 | | /// If the node is full, this leaves the node unchanged and returns false. |
167 | 36.9k | pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool { |
168 | 36.9k | match *self { |
169 | | Self::Inner { |
170 | 36.9k | ref mut size, |
171 | 36.9k | ref mut keys, |
172 | 36.9k | ref mut tree, |
173 | | } => { |
174 | 36.9k | let sz = usize::from(*size); |
175 | 36.9k | debug_assert!(sz <= keys.len()); |
176 | 36.9k | debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys"); |
177 | | |
178 | 36.9k | if let Some(ks) = keys.get_mut(0..=sz) { |
179 | 31.8k | *size = (sz + 1) as u8; |
180 | 31.8k | slice_insert(ks, index, key); |
181 | 31.8k | slice_insert(&mut tree[1..=sz + 1], index, node); |
182 | 31.8k | true |
183 | | } else { |
184 | 5.11k | false |
185 | | } |
186 | | } |
187 | 0 | _ => panic!("Expected inner node"), |
188 | | } |
189 | 36.9k | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::try_inner_insert Line | Count | Source | 167 | 6.06k | pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool { | 168 | 6.06k | match *self { | 169 | | Self::Inner { | 170 | 6.06k | ref mut size, | 171 | 6.06k | ref mut keys, | 172 | 6.06k | ref mut tree, | 173 | | } => { | 174 | 6.06k | let sz = usize::from(*size); | 175 | 6.06k | debug_assert!(sz <= keys.len()); | 176 | 6.06k | debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys"); | 177 | | | 178 | 6.06k | if let Some(ks) = keys.get_mut(0..=sz) { | 179 | 5.13k | *size = (sz + 1) as u8; | 180 | 5.13k | slice_insert(ks, index, key); | 181 | 5.13k | slice_insert(&mut tree[1..=sz + 1], index, node); | 182 | 5.13k | true | 183 | | } else { | 184 | 924 | false | 185 | | } | 186 | | } | 187 | 0 | _ => panic!("Expected inner node"), | 188 | | } | 189 | 6.06k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::try_inner_insert Line | Count | Source | 167 | 56 | pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool { | 168 | 56 | match *self { | 169 | | Self::Inner { | 170 | 56 | ref mut size, | 171 | 56 | ref mut keys, | 172 | 56 | ref mut tree, | 173 | | } => { | 174 | 56 | let sz = usize::from(*size); | 175 | 56 | debug_assert!(sz <= keys.len()); | 176 | 56 | debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys"); | 177 | | | 178 | 56 | if let Some(ks) = keys.get_mut(0..=sz) { | 179 | 56 | *size = (sz + 1) as u8; | 180 | 56 | slice_insert(ks, index, key); | 181 | 56 | slice_insert(&mut tree[1..=sz + 1], index, node); | 182 | 56 | true | 183 | | } else { | 184 | 0 | false | 185 | | } | 186 | | } | 187 | 0 | _ => panic!("Expected inner node"), | 188 | | } | 189 | 56 | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::try_inner_insert <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::try_inner_insert Line | Count | Source | 167 | 28.2k | pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool { | 168 | 28.2k | match *self { | 169 | | Self::Inner { | 170 | 28.2k | ref mut size, | 171 | 28.2k | ref mut keys, | 172 | 28.2k | ref mut tree, | 173 | | } => { | 174 | 28.2k | let sz = usize::from(*size); | 175 | 28.2k | debug_assert!(sz <= keys.len()); | 176 | 28.2k | debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys"); | 177 | | | 178 | 28.2k | if let Some(ks) = keys.get_mut(0..=sz) { | 179 | 24.3k | *size = (sz + 1) as u8; | 180 | 24.3k | slice_insert(ks, index, key); | 181 | 24.3k | slice_insert(&mut tree[1..=sz + 1], index, node); | 182 | 24.3k | true | 183 | | } else { | 184 | 3.93k | false | 185 | | } | 186 | | } | 187 | 0 | _ => panic!("Expected inner node"), | 188 | | } | 189 | 28.2k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::try_inner_insert Line | Count | Source | 167 | 2.56k | pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool { | 168 | 2.56k | match *self { | 169 | | Self::Inner { | 170 | 2.56k | ref mut size, | 171 | 2.56k | ref mut keys, | 172 | 2.56k | ref mut tree, | 173 | | } => { | 174 | 2.56k | let sz = usize::from(*size); | 175 | 2.56k | debug_assert!(sz <= keys.len()); | 176 | 2.56k | debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys"); | 177 | | | 178 | 2.56k | if let Some(ks) = keys.get_mut(0..=sz) { | 179 | 2.31k | *size = (sz + 1) as u8; | 180 | 2.31k | slice_insert(ks, index, key); | 181 | 2.31k | slice_insert(&mut tree[1..=sz + 1], index, node); | 182 | 2.31k | true | 183 | | } else { | 184 | 252 | false | 185 | | } | 186 | | } | 187 | 0 | _ => panic!("Expected inner node"), | 188 | | } | 189 | 2.56k | } |
|
190 | | |
191 | | /// Try to insert `key, value` at `index` in a leaf node, but fail and return false if the node |
192 | | /// is full. |
193 | 5.16M | pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool { |
194 | 5.16M | match *self { |
195 | | Self::Leaf { |
196 | 5.16M | ref mut size, |
197 | 5.16M | ref mut keys, |
198 | 5.16M | ref mut vals, |
199 | | } => { |
200 | 5.16M | let sz = usize::from(*size); |
201 | 5.16M | let keys = keys.borrow_mut(); |
202 | 5.16M | let vals = vals.borrow_mut(); |
203 | 5.16M | debug_assert!(sz <= keys.len()); |
204 | 5.16M | debug_assert!(index <= sz); |
205 | | |
206 | 5.16M | if let Some(ks) = keys.get_mut(0..=sz) { |
207 | 5.12M | *size = (sz + 1) as u8; |
208 | 5.12M | slice_insert(ks, index, key); |
209 | 5.12M | slice_insert(&mut vals[0..=sz], index, value); |
210 | 5.12M | true |
211 | | } else { |
212 | 33.4k | false |
213 | | } |
214 | | } |
215 | 0 | _ => panic!("Expected leaf node"), |
216 | | } |
217 | 5.16M | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::try_leaf_insert Line | Count | Source | 193 | 236k | pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool { | 194 | 236k | match *self { | 195 | | Self::Leaf { | 196 | 236k | ref mut size, | 197 | 236k | ref mut keys, | 198 | 236k | ref mut vals, | 199 | | } => { | 200 | 236k | let sz = usize::from(*size); | 201 | 236k | let keys = keys.borrow_mut(); | 202 | 236k | let vals = vals.borrow_mut(); | 203 | 236k | debug_assert!(sz <= keys.len()); | 204 | 236k | debug_assert!(index <= sz); | 205 | | | 206 | 236k | if let Some(ks) = keys.get_mut(0..=sz) { | 207 | 232k | *size = (sz + 1) as u8; | 208 | 232k | slice_insert(ks, index, key); | 209 | 232k | slice_insert(&mut vals[0..=sz], index, value); | 210 | 232k | true | 211 | | } else { | 212 | 4.69k | false | 213 | | } | 214 | | } | 215 | 0 | _ => panic!("Expected leaf node"), | 216 | | } | 217 | 236k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::try_leaf_insert Line | Count | Source | 193 | 229k | pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool { | 194 | 229k | match *self { | 195 | | Self::Leaf { | 196 | 229k | ref mut size, | 197 | 229k | ref mut keys, | 198 | 229k | ref mut vals, | 199 | | } => { | 200 | 229k | let sz = usize::from(*size); | 201 | 229k | let keys = keys.borrow_mut(); | 202 | 229k | let vals = vals.borrow_mut(); | 203 | 229k | debug_assert!(sz <= keys.len()); | 204 | 229k | debug_assert!(index <= sz); | 205 | | | 206 | 229k | if let Some(ks) = keys.get_mut(0..=sz) { | 207 | 228k | *size = (sz + 1) as u8; | 208 | 228k | slice_insert(ks, index, key); | 209 | 228k | slice_insert(&mut vals[0..=sz], index, value); | 210 | 228k | true | 211 | | } else { | 212 | 84 | false | 213 | | } | 214 | | } | 215 | 0 | _ => panic!("Expected leaf node"), | 216 | | } | 217 | 229k | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::try_leaf_insert <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::try_leaf_insert Line | Count | Source | 193 | 1.97M | pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool { | 194 | 1.97M | match *self { | 195 | | Self::Leaf { | 196 | 1.97M | ref mut size, | 197 | 1.97M | ref mut keys, | 198 | 1.97M | ref mut vals, | 199 | | } => { | 200 | 1.97M | let sz = usize::from(*size); | 201 | 1.97M | let keys = keys.borrow_mut(); | 202 | 1.97M | let vals = vals.borrow_mut(); | 203 | 1.97M | debug_assert!(sz <= keys.len()); | 204 | 1.97M | debug_assert!(index <= sz); | 205 | | | 206 | 1.97M | if let Some(ks) = keys.get_mut(0..=sz) { | 207 | 1.95M | *size = (sz + 1) as u8; | 208 | 1.95M | slice_insert(ks, index, key); | 209 | 1.95M | slice_insert(&mut vals[0..=sz], index, value); | 210 | 1.95M | true | 211 | | } else { | 212 | 25.9k | false | 213 | | } | 214 | | } | 215 | 0 | _ => panic!("Expected leaf node"), | 216 | | } | 217 | 1.97M | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::try_leaf_insert Line | Count | Source | 193 | 2.72M | pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool { | 194 | 2.72M | match *self { | 195 | | Self::Leaf { | 196 | 2.72M | ref mut size, | 197 | 2.72M | ref mut keys, | 198 | 2.72M | ref mut vals, | 199 | | } => { | 200 | 2.72M | let sz = usize::from(*size); | 201 | 2.72M | let keys = keys.borrow_mut(); | 202 | 2.72M | let vals = vals.borrow_mut(); | 203 | 2.72M | debug_assert!(sz <= keys.len()); | 204 | 2.72M | debug_assert!(index <= sz); | 205 | | | 206 | 2.72M | if let Some(ks) = keys.get_mut(0..=sz) { | 207 | 2.71M | *size = (sz + 1) as u8; | 208 | 2.71M | slice_insert(ks, index, key); | 209 | 2.71M | slice_insert(&mut vals[0..=sz], index, value); | 210 | 2.71M | true | 211 | | } else { | 212 | 2.72k | false | 213 | | } | 214 | | } | 215 | 0 | _ => panic!("Expected leaf node"), | 216 | | } | 217 | 2.72M | } |
|
218 | | |
219 | | /// Split off the second half of this node. |
220 | | /// It is assumed that this a completely full inner or leaf node. |
221 | | /// |
222 | | /// The `insert_index` parameter is the position where an insertion was tried and failed. The |
223 | | /// node will be split in half with a bias towards an even split after the insertion is retried. |
224 | 38.5k | pub fn split(&mut self, insert_index: usize) -> SplitOff<F> { |
225 | 38.5k | match *self { |
226 | | Self::Inner { |
227 | 5.11k | ref mut size, |
228 | 5.11k | ref keys, |
229 | 5.11k | ref tree, |
230 | | } => { |
231 | 5.11k | debug_assert_eq!(usize::from(*size), keys.len(), "Node not full"); |
232 | | |
233 | | // Number of tree entries in the lhs node. |
234 | 5.11k | let l_ents = split_pos(tree.len(), insert_index + 1); |
235 | 5.11k | let r_ents = tree.len() - l_ents; |
236 | | |
237 | | // With INNER_SIZE=8, we get l_ents=4 and: |
238 | | // |
239 | | // self: [ n0 k0 n1 k1 n2 k2 n3 k3 n4 k4 n5 k5 n6 k6 n7 ] |
240 | | // lhs: [ n0 k0 n1 k1 n2 k2 n3 ] |
241 | | // crit_key = k3 (not present in either node) |
242 | | // rhs: [ n4 k4 n5 k5 n6 k6 n7 ] |
243 | | |
244 | | // 1. Truncate the LHS. |
245 | 5.11k | *size = (l_ents - 1) as u8; |
246 | | |
247 | | // 2. Copy second half to `rhs_data`. |
248 | 5.11k | let mut r_keys = *keys; |
249 | 5.11k | r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]); |
250 | | |
251 | 5.11k | let mut r_tree = *tree; |
252 | 5.11k | r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]); |
253 | | |
254 | 5.11k | SplitOff { |
255 | 5.11k | lhs_entries: l_ents, |
256 | 5.11k | rhs_entries: r_ents, |
257 | 5.11k | crit_key: keys[l_ents - 1], |
258 | 5.11k | rhs_data: Self::Inner { |
259 | 5.11k | size: (r_ents - 1) as u8, |
260 | 5.11k | keys: r_keys, |
261 | 5.11k | tree: r_tree, |
262 | 5.11k | }, |
263 | 5.11k | } |
264 | | } |
265 | | Self::Leaf { |
266 | 33.4k | ref mut size, |
267 | 33.4k | ref keys, |
268 | 33.4k | ref vals, |
269 | | } => { |
270 | 33.4k | let o_keys = keys.borrow(); |
271 | 33.4k | let o_vals = vals.borrow(); |
272 | 33.4k | debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full"); |
273 | | |
274 | 33.4k | let l_size = split_pos(o_keys.len(), insert_index); |
275 | 33.4k | let r_size = o_keys.len() - l_size; |
276 | | |
277 | | // 1. Truncate the LHS node at `l_size`. |
278 | 33.4k | *size = l_size as u8; |
279 | | |
280 | | // 2. Copy second half to `rhs_data`. |
281 | 33.4k | let mut r_keys = *keys; |
282 | 33.4k | r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]); |
283 | | |
284 | 33.4k | let mut r_vals = *vals; |
285 | 33.4k | r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]); |
286 | | |
287 | 33.4k | SplitOff { |
288 | 33.4k | lhs_entries: l_size, |
289 | 33.4k | rhs_entries: r_size, |
290 | 33.4k | crit_key: o_keys[l_size], |
291 | 33.4k | rhs_data: Self::Leaf { |
292 | 33.4k | size: r_size as u8, |
293 | 33.4k | keys: r_keys, |
294 | 33.4k | vals: r_vals, |
295 | 33.4k | }, |
296 | 33.4k | } |
297 | | } |
298 | 0 | _ => panic!("Expected leaf node"), |
299 | | } |
300 | 38.5k | } <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::split Line | Count | Source | 224 | 5.61k | pub fn split(&mut self, insert_index: usize) -> SplitOff<F> { | 225 | 5.61k | match *self { | 226 | | Self::Inner { | 227 | 924 | ref mut size, | 228 | 924 | ref keys, | 229 | 924 | ref tree, | 230 | | } => { | 231 | 924 | debug_assert_eq!(usize::from(*size), keys.len(), "Node not full"); | 232 | | | 233 | | // Number of tree entries in the lhs node. | 234 | 924 | let l_ents = split_pos(tree.len(), insert_index + 1); | 235 | 924 | let r_ents = tree.len() - l_ents; | 236 | | | 237 | | // With INNER_SIZE=8, we get l_ents=4 and: | 238 | | // | 239 | | // self: [ n0 k0 n1 k1 n2 k2 n3 k3 n4 k4 n5 k5 n6 k6 n7 ] | 240 | | // lhs: [ n0 k0 n1 k1 n2 k2 n3 ] | 241 | | // crit_key = k3 (not present in either node) | 242 | | // rhs: [ n4 k4 n5 k5 n6 k6 n7 ] | 243 | | | 244 | | // 1. Truncate the LHS. | 245 | 924 | *size = (l_ents - 1) as u8; | 246 | | | 247 | | // 2. Copy second half to `rhs_data`. | 248 | 924 | let mut r_keys = *keys; | 249 | 924 | r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]); | 250 | | | 251 | 924 | let mut r_tree = *tree; | 252 | 924 | r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]); | 253 | | | 254 | 924 | SplitOff { | 255 | 924 | lhs_entries: l_ents, | 256 | 924 | rhs_entries: r_ents, | 257 | 924 | crit_key: keys[l_ents - 1], | 258 | 924 | rhs_data: Self::Inner { | 259 | 924 | size: (r_ents - 1) as u8, | 260 | 924 | keys: r_keys, | 261 | 924 | tree: r_tree, | 262 | 924 | }, | 263 | 924 | } | 264 | | } | 265 | | Self::Leaf { | 266 | 4.69k | ref mut size, | 267 | 4.69k | ref keys, | 268 | 4.69k | ref vals, | 269 | | } => { | 270 | 4.69k | let o_keys = keys.borrow(); | 271 | 4.69k | let o_vals = vals.borrow(); | 272 | 4.69k | debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full"); | 273 | | | 274 | 4.69k | let l_size = split_pos(o_keys.len(), insert_index); | 275 | 4.69k | let r_size = o_keys.len() - l_size; | 276 | | | 277 | | // 1. Truncate the LHS node at `l_size`. | 278 | 4.69k | *size = l_size as u8; | 279 | | | 280 | | // 2. Copy second half to `rhs_data`. | 281 | 4.69k | let mut r_keys = *keys; | 282 | 4.69k | r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]); | 283 | | | 284 | 4.69k | let mut r_vals = *vals; | 285 | 4.69k | r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]); | 286 | | | 287 | 4.69k | SplitOff { | 288 | 4.69k | lhs_entries: l_size, | 289 | 4.69k | rhs_entries: r_size, | 290 | 4.69k | crit_key: o_keys[l_size], | 291 | 4.69k | rhs_data: Self::Leaf { | 292 | 4.69k | size: r_size as u8, | 293 | 4.69k | keys: r_keys, | 294 | 4.69k | vals: r_vals, | 295 | 4.69k | }, | 296 | 4.69k | } | 297 | | } | 298 | 0 | _ => panic!("Expected leaf node"), | 299 | | } | 300 | 5.61k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::split Line | Count | Source | 224 | 84 | pub fn split(&mut self, insert_index: usize) -> SplitOff<F> { | 225 | 84 | match *self { | 226 | | Self::Inner { | 227 | 0 | ref mut size, | 228 | 0 | ref keys, | 229 | 0 | ref tree, | 230 | | } => { | 231 | 0 | debug_assert_eq!(usize::from(*size), keys.len(), "Node not full"); | 232 | | | 233 | | // Number of tree entries in the lhs node. | 234 | 0 | let l_ents = split_pos(tree.len(), insert_index + 1); | 235 | 0 | let r_ents = tree.len() - l_ents; | 236 | | | 237 | | // With INNER_SIZE=8, we get l_ents=4 and: | 238 | | // | 239 | | // self: [ n0 k0 n1 k1 n2 k2 n3 k3 n4 k4 n5 k5 n6 k6 n7 ] | 240 | | // lhs: [ n0 k0 n1 k1 n2 k2 n3 ] | 241 | | // crit_key = k3 (not present in either node) | 242 | | // rhs: [ n4 k4 n5 k5 n6 k6 n7 ] | 243 | | | 244 | | // 1. Truncate the LHS. | 245 | 0 | *size = (l_ents - 1) as u8; | 246 | | | 247 | | // 2. Copy second half to `rhs_data`. | 248 | 0 | let mut r_keys = *keys; | 249 | 0 | r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]); | 250 | | | 251 | 0 | let mut r_tree = *tree; | 252 | 0 | r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]); | 253 | | | 254 | 0 | SplitOff { | 255 | 0 | lhs_entries: l_ents, | 256 | 0 | rhs_entries: r_ents, | 257 | 0 | crit_key: keys[l_ents - 1], | 258 | 0 | rhs_data: Self::Inner { | 259 | 0 | size: (r_ents - 1) as u8, | 260 | 0 | keys: r_keys, | 261 | 0 | tree: r_tree, | 262 | 0 | }, | 263 | 0 | } | 264 | | } | 265 | | Self::Leaf { | 266 | 84 | ref mut size, | 267 | 84 | ref keys, | 268 | 84 | ref vals, | 269 | | } => { | 270 | 84 | let o_keys = keys.borrow(); | 271 | 84 | let o_vals = vals.borrow(); | 272 | 84 | debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full"); | 273 | | | 274 | 84 | let l_size = split_pos(o_keys.len(), insert_index); | 275 | 84 | let r_size = o_keys.len() - l_size; | 276 | | | 277 | | // 1. Truncate the LHS node at `l_size`. | 278 | 84 | *size = l_size as u8; | 279 | | | 280 | | // 2. Copy second half to `rhs_data`. | 281 | 84 | let mut r_keys = *keys; | 282 | 84 | r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]); | 283 | | | 284 | 84 | let mut r_vals = *vals; | 285 | 84 | r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]); | 286 | | | 287 | 84 | SplitOff { | 288 | 84 | lhs_entries: l_size, | 289 | 84 | rhs_entries: r_size, | 290 | 84 | crit_key: o_keys[l_size], | 291 | 84 | rhs_data: Self::Leaf { | 292 | 84 | size: r_size as u8, | 293 | 84 | keys: r_keys, | 294 | 84 | vals: r_vals, | 295 | 84 | }, | 296 | 84 | } | 297 | | } | 298 | 0 | _ => panic!("Expected leaf node"), | 299 | | } | 300 | 84 | } |
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::split <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::split Line | Count | Source | 224 | 29.8k | pub fn split(&mut self, insert_index: usize) -> SplitOff<F> { | 225 | 29.8k | match *self { | 226 | | Self::Inner { | 227 | 3.93k | ref mut size, | 228 | 3.93k | ref keys, | 229 | 3.93k | ref tree, | 230 | | } => { | 231 | 3.93k | debug_assert_eq!(usize::from(*size), keys.len(), "Node not full"); | 232 | | | 233 | | // Number of tree entries in the lhs node. | 234 | 3.93k | let l_ents = split_pos(tree.len(), insert_index + 1); | 235 | 3.93k | let r_ents = tree.len() - l_ents; | 236 | | | 237 | | // With INNER_SIZE=8, we get l_ents=4 and: | 238 | | // | 239 | | // self: [ n0 k0 n1 k1 n2 k2 n3 k3 n4 k4 n5 k5 n6 k6 n7 ] | 240 | | // lhs: [ n0 k0 n1 k1 n2 k2 n3 ] | 241 | | // crit_key = k3 (not present in either node) | 242 | | // rhs: [ n4 k4 n5 k5 n6 k6 n7 ] | 243 | | | 244 | | // 1. Truncate the LHS. | 245 | 3.93k | *size = (l_ents - 1) as u8; | 246 | | | 247 | | // 2. Copy second half to `rhs_data`. | 248 | 3.93k | let mut r_keys = *keys; | 249 | 3.93k | r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]); | 250 | | | 251 | 3.93k | let mut r_tree = *tree; | 252 | 3.93k | r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]); | 253 | | | 254 | 3.93k | SplitOff { | 255 | 3.93k | lhs_entries: l_ents, | 256 | 3.93k | rhs_entries: r_ents, | 257 | 3.93k | crit_key: keys[l_ents - 1], | 258 | 3.93k | rhs_data: Self::Inner { | 259 | 3.93k | size: (r_ents - 1) as u8, | 260 | 3.93k | keys: r_keys, | 261 | 3.93k | tree: r_tree, | 262 | 3.93k | }, | 263 | 3.93k | } | 264 | | } | 265 | | Self::Leaf { | 266 | 25.9k | ref mut size, | 267 | 25.9k | ref keys, | 268 | 25.9k | ref vals, | 269 | | } => { | 270 | 25.9k | let o_keys = keys.borrow(); | 271 | 25.9k | let o_vals = vals.borrow(); | 272 | 25.9k | debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full"); | 273 | | | 274 | 25.9k | let l_size = split_pos(o_keys.len(), insert_index); | 275 | 25.9k | let r_size = o_keys.len() - l_size; | 276 | | | 277 | | // 1. Truncate the LHS node at `l_size`. | 278 | 25.9k | *size = l_size as u8; | 279 | | | 280 | | // 2. Copy second half to `rhs_data`. | 281 | 25.9k | let mut r_keys = *keys; | 282 | 25.9k | r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]); | 283 | | | 284 | 25.9k | let mut r_vals = *vals; | 285 | 25.9k | r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]); | 286 | | | 287 | 25.9k | SplitOff { | 288 | 25.9k | lhs_entries: l_size, | 289 | 25.9k | rhs_entries: r_size, | 290 | 25.9k | crit_key: o_keys[l_size], | 291 | 25.9k | rhs_data: Self::Leaf { | 292 | 25.9k | size: r_size as u8, | 293 | 25.9k | keys: r_keys, | 294 | 25.9k | vals: r_vals, | 295 | 25.9k | }, | 296 | 25.9k | } | 297 | | } | 298 | 0 | _ => panic!("Expected leaf node"), | 299 | | } | 300 | 29.8k | } |
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::split Line | Count | Source | 224 | 2.97k | pub fn split(&mut self, insert_index: usize) -> SplitOff<F> { | 225 | 2.97k | match *self { | 226 | | Self::Inner { | 227 | 252 | ref mut size, | 228 | 252 | ref keys, | 229 | 252 | ref tree, | 230 | | } => { | 231 | 252 | debug_assert_eq!(usize::from(*size), keys.len(), "Node not full"); | 232 | | | 233 | | // Number of tree entries in the lhs node. | 234 | 252 | let l_ents = split_pos(tree.len(), insert_index + 1); | 235 | 252 | let r_ents = tree.len() - l_ents; | 236 | | | 237 | | // With INNER_SIZE=8, we get l_ents=4 and: | 238 | | // | 239 | | // self: [ n0 k0 n1 k1 n2 k2 n3 k3 n4 k4 n5 k5 n6 k6 n7 ] | 240 | | // lhs: [ n0 k0 n1 k1 n2 k2 n3 ] | 241 | | // crit_key = k3 (not present in either node) | 242 | | // rhs: [ n4 k4 n5 k5 n6 k6 n7 ] | 243 | | | 244 | | // 1. Truncate the LHS. | 245 | 252 | *size = (l_ents - 1) as u8; | 246 | | | 247 | | // 2. Copy second half to `rhs_data`. | 248 | 252 | let mut r_keys = *keys; | 249 | 252 | r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]); | 250 | | | 251 | 252 | let mut r_tree = *tree; | 252 | 252 | r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]); | 253 | | | 254 | 252 | SplitOff { | 255 | 252 | lhs_entries: l_ents, | 256 | 252 | rhs_entries: r_ents, | 257 | 252 | crit_key: keys[l_ents - 1], | 258 | 252 | rhs_data: Self::Inner { | 259 | 252 | size: (r_ents - 1) as u8, | 260 | 252 | keys: r_keys, | 261 | 252 | tree: r_tree, | 262 | 252 | }, | 263 | 252 | } | 264 | | } | 265 | | Self::Leaf { | 266 | 2.72k | ref mut size, | 267 | 2.72k | ref keys, | 268 | 2.72k | ref vals, | 269 | | } => { | 270 | 2.72k | let o_keys = keys.borrow(); | 271 | 2.72k | let o_vals = vals.borrow(); | 272 | 2.72k | debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full"); | 273 | | | 274 | 2.72k | let l_size = split_pos(o_keys.len(), insert_index); | 275 | 2.72k | let r_size = o_keys.len() - l_size; | 276 | | | 277 | | // 1. Truncate the LHS node at `l_size`. | 278 | 2.72k | *size = l_size as u8; | 279 | | | 280 | | // 2. Copy second half to `rhs_data`. | 281 | 2.72k | let mut r_keys = *keys; | 282 | 2.72k | r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]); | 283 | | | 284 | 2.72k | let mut r_vals = *vals; | 285 | 2.72k | r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]); | 286 | | | 287 | 2.72k | SplitOff { | 288 | 2.72k | lhs_entries: l_size, | 289 | 2.72k | rhs_entries: r_size, | 290 | 2.72k | crit_key: o_keys[l_size], | 291 | 2.72k | rhs_data: Self::Leaf { | 292 | 2.72k | size: r_size as u8, | 293 | 2.72k | keys: r_keys, | 294 | 2.72k | vals: r_vals, | 295 | 2.72k | }, | 296 | 2.72k | } | 297 | | } | 298 | 0 | _ => panic!("Expected leaf node"), | 299 | | } | 300 | 2.97k | } |
|
301 | | |
302 | | /// Remove the sub-tree at `index` from this inner node. |
303 | | /// |
304 | | /// Note that `index` refers to a sub-tree entry and not a key entry as it does for |
305 | | /// `try_inner_insert()`. It is possible to remove the first sub-tree (which can't be inserted |
306 | | /// by `try_inner_insert()`). |
307 | | /// |
308 | | /// Return an indication of the node's health (i.e. below half capacity). |
309 | 6.04k | pub fn inner_remove(&mut self, index: usize) -> Removed { |
310 | 6.04k | match *self { |
311 | | Self::Inner { |
312 | 6.04k | ref mut size, |
313 | 6.04k | ref mut keys, |
314 | 6.04k | ref mut tree, |
315 | | } => { |
316 | 6.04k | let ents = usize::from(*size) + 1; |
317 | 6.04k | debug_assert!(ents <= tree.len()); |
318 | 6.04k | debug_assert!(index < ents); |
319 | | // Leave an invalid 0xff size when node becomes empty. |
320 | 6.04k | *size = ents.wrapping_sub(2) as u8; |
321 | 6.04k | if ents > 1 { |
322 | 6.04k | slice_shift(&mut keys[index.saturating_sub(1)..ents - 1], 1); |
323 | 6.04k | } |
324 | 6.04k | slice_shift(&mut tree[index..ents], 1); |
325 | 6.04k | Removed::new(index, ents - 1, tree.len()) |
326 | | } |
327 | 0 | _ => panic!("Expected inner node"), |
328 | | } |
329 | 6.04k | } Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::inner_remove Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::inner_remove <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::inner_remove Line | Count | Source | 309 | 6.04k | pub fn inner_remove(&mut self, index: usize) -> Removed { | 310 | 6.04k | match *self { | 311 | | Self::Inner { | 312 | 6.04k | ref mut size, | 313 | 6.04k | ref mut keys, | 314 | 6.04k | ref mut tree, | 315 | | } => { | 316 | 6.04k | let ents = usize::from(*size) + 1; | 317 | 6.04k | debug_assert!(ents <= tree.len()); | 318 | 6.04k | debug_assert!(index < ents); | 319 | | // Leave an invalid 0xff size when node becomes empty. | 320 | 6.04k | *size = ents.wrapping_sub(2) as u8; | 321 | 6.04k | if ents > 1 { | 322 | 6.04k | slice_shift(&mut keys[index.saturating_sub(1)..ents - 1], 1); | 323 | 6.04k | } | 324 | 6.04k | slice_shift(&mut tree[index..ents], 1); | 325 | 6.04k | Removed::new(index, ents - 1, tree.len()) | 326 | | } | 327 | 0 | _ => panic!("Expected inner node"), | 328 | | } | 329 | 6.04k | } |
|
330 | | |
331 | | /// Remove the key-value pair at `index` from this leaf node. |
332 | | /// |
333 | | /// Return an indication of the node's health (i.e. below half capacity). |
334 | 326k | pub fn leaf_remove(&mut self, index: usize) -> Removed { |
335 | 326k | match *self { |
336 | | Self::Leaf { |
337 | 326k | ref mut size, |
338 | 326k | ref mut keys, |
339 | 326k | ref mut vals, |
340 | | } => { |
341 | 326k | let sz = usize::from(*size); |
342 | 326k | let keys = keys.borrow_mut(); |
343 | 326k | let vals = vals.borrow_mut(); |
344 | 326k | *size -= 1; |
345 | 326k | slice_shift(&mut keys[index..sz], 1); |
346 | 326k | slice_shift(&mut vals[index..sz], 1); |
347 | 326k | Removed::new(index, sz - 1, keys.len()) |
348 | | } |
349 | 0 | _ => panic!("Expected leaf node"), |
350 | | } |
351 | 326k | } Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf_remove Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::leaf_remove <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf_remove Line | Count | Source | 334 | 326k | pub fn leaf_remove(&mut self, index: usize) -> Removed { | 335 | 326k | match *self { | 336 | | Self::Leaf { | 337 | 326k | ref mut size, | 338 | 326k | ref mut keys, | 339 | 326k | ref mut vals, | 340 | | } => { | 341 | 326k | let sz = usize::from(*size); | 342 | 326k | let keys = keys.borrow_mut(); | 343 | 326k | let vals = vals.borrow_mut(); | 344 | 326k | *size -= 1; | 345 | 326k | slice_shift(&mut keys[index..sz], 1); | 346 | 326k | slice_shift(&mut vals[index..sz], 1); | 347 | 326k | Removed::new(index, sz - 1, keys.len()) | 348 | | } | 349 | 0 | _ => panic!("Expected leaf node"), | 350 | | } | 351 | 326k | } |
|
352 | | |
353 | | /// Balance this node with its right sibling. |
354 | | /// |
355 | | /// It is assumed that the current node has underflowed. Look at the right sibling node and do |
356 | | /// one of two things: |
357 | | /// |
358 | | /// 1. Move all entries to the right node, leaving this node empty, or |
359 | | /// 2. Distribute entries evenly between the two nodes. |
360 | | /// |
361 | | /// In the first case, `None` is returned. In the second case, the new critical key for the |
362 | | /// right sibling node is returned. |
363 | 6.82k | pub fn balance(&mut self, crit_key: F::Key, rhs: &mut Self) -> Option<F::Key> { |
364 | 6.82k | match (self, rhs) { |
365 | | ( |
366 | | &mut Self::Inner { |
367 | 997 | size: ref mut l_size, |
368 | 997 | keys: ref mut l_keys, |
369 | 997 | tree: ref mut l_tree, |
370 | | }, |
371 | | &mut Self::Inner { |
372 | 997 | size: ref mut r_size, |
373 | 997 | keys: ref mut r_keys, |
374 | 997 | tree: ref mut r_tree, |
375 | | }, |
376 | | ) => { |
377 | 997 | let l_ents = usize::from(*l_size) + 1; |
378 | 997 | let r_ents = usize::from(*r_size) + 1; |
379 | 997 | let ents = l_ents + r_ents; |
380 | | |
381 | 997 | if ents <= r_tree.len() { |
382 | | // All entries will fit in the RHS node. |
383 | | // We'll leave the LHS node empty, but first use it as a scratch space. |
384 | 880 | *l_size = 0; |
385 | | // Insert `crit_key` between the two nodes. |
386 | 880 | l_keys[l_ents - 1] = crit_key; |
387 | 880 | l_keys[l_ents..ents - 1].copy_from_slice(&r_keys[0..r_ents - 1]); |
388 | 880 | r_keys[0..ents - 1].copy_from_slice(&l_keys[0..ents - 1]); |
389 | 880 | l_tree[l_ents..ents].copy_from_slice(&r_tree[0..r_ents]); |
390 | 880 | r_tree[0..ents].copy_from_slice(&l_tree[0..ents]); |
391 | 880 | *r_size = (ents - 1) as u8; |
392 | 880 | None |
393 | | } else { |
394 | | // The entries don't all fit in one node. Distribute some from RHS -> LHS. |
395 | | // Split evenly with a bias to putting one entry in LHS. |
396 | 117 | let r_goal = ents / 2; |
397 | 117 | let l_goal = ents - r_goal; |
398 | 117 | debug_assert!(l_goal > l_ents, "Node must be underflowed"); |
399 | | |
400 | 117 | l_keys[l_ents - 1] = crit_key; |
401 | 117 | l_keys[l_ents..l_goal - 1].copy_from_slice(&r_keys[0..l_goal - 1 - l_ents]); |
402 | 117 | l_tree[l_ents..l_goal].copy_from_slice(&r_tree[0..l_goal - l_ents]); |
403 | 117 | *l_size = (l_goal - 1) as u8; |
404 | | |
405 | 117 | let new_crit = r_keys[r_ents - r_goal - 1]; |
406 | 117 | slice_shift(&mut r_keys[0..r_ents - 1], r_ents - r_goal); |
407 | 117 | slice_shift(&mut r_tree[0..r_ents], r_ents - r_goal); |
408 | 117 | *r_size = (r_goal - 1) as u8; |
409 | | |
410 | 117 | Some(new_crit) |
411 | | } |
412 | | } |
413 | | ( |
414 | | &mut Self::Leaf { |
415 | 5.83k | size: ref mut l_size, |
416 | 5.83k | keys: ref mut l_keys, |
417 | 5.83k | vals: ref mut l_vals, |
418 | | }, |
419 | | &mut Self::Leaf { |
420 | 5.83k | size: ref mut r_size, |
421 | 5.83k | keys: ref mut r_keys, |
422 | 5.83k | vals: ref mut r_vals, |
423 | | }, |
424 | | ) => { |
425 | 5.83k | let l_ents = usize::from(*l_size); |
426 | 5.83k | let l_keys = l_keys.borrow_mut(); |
427 | 5.83k | let l_vals = l_vals.borrow_mut(); |
428 | 5.83k | let r_ents = usize::from(*r_size); |
429 | 5.83k | let r_keys = r_keys.borrow_mut(); |
430 | 5.83k | let r_vals = r_vals.borrow_mut(); |
431 | 5.83k | let ents = l_ents + r_ents; |
432 | | |
433 | 5.83k | if ents <= r_vals.len() { |
434 | | // We can fit all entries in the RHS node. |
435 | | // We'll leave the LHS node empty, but first use it as a scratch space. |
436 | 5.16k | *l_size = 0; |
437 | 5.16k | l_keys[l_ents..ents].copy_from_slice(&r_keys[0..r_ents]); |
438 | 5.16k | r_keys[0..ents].copy_from_slice(&l_keys[0..ents]); |
439 | 5.16k | l_vals[l_ents..ents].copy_from_slice(&r_vals[0..r_ents]); |
440 | 5.16k | r_vals[0..ents].copy_from_slice(&l_vals[0..ents]); |
441 | 5.16k | *r_size = ents as u8; |
442 | 5.16k | None |
443 | | } else { |
444 | | // The entries don't all fit in one node. Distribute some from RHS -> LHS. |
445 | | // Split evenly with a bias to putting one entry in LHS. |
446 | 666 | let r_goal = ents / 2; |
447 | 666 | let l_goal = ents - r_goal; |
448 | 666 | debug_assert!(l_goal > l_ents, "Node must be underflowed"); |
449 | | |
450 | 666 | l_keys[l_ents..l_goal].copy_from_slice(&r_keys[0..l_goal - l_ents]); |
451 | 666 | l_vals[l_ents..l_goal].copy_from_slice(&r_vals[0..l_goal - l_ents]); |
452 | 666 | *l_size = l_goal as u8; |
453 | | |
454 | 666 | slice_shift(&mut r_keys[0..r_ents], r_ents - r_goal); |
455 | 666 | slice_shift(&mut r_vals[0..r_ents], r_ents - r_goal); |
456 | 666 | *r_size = r_goal as u8; |
457 | | |
458 | 666 | Some(r_keys[0]) |
459 | | } |
460 | | } |
461 | 0 | _ => panic!("Mismatched nodes"), |
462 | | } |
463 | 6.82k | } Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::balance Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::balance <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::balance Line | Count | Source | 363 | 6.82k | pub fn balance(&mut self, crit_key: F::Key, rhs: &mut Self) -> Option<F::Key> { | 364 | 6.82k | match (self, rhs) { | 365 | | ( | 366 | | &mut Self::Inner { | 367 | 997 | size: ref mut l_size, | 368 | 997 | keys: ref mut l_keys, | 369 | 997 | tree: ref mut l_tree, | 370 | | }, | 371 | | &mut Self::Inner { | 372 | 997 | size: ref mut r_size, | 373 | 997 | keys: ref mut r_keys, | 374 | 997 | tree: ref mut r_tree, | 375 | | }, | 376 | | ) => { | 377 | 997 | let l_ents = usize::from(*l_size) + 1; | 378 | 997 | let r_ents = usize::from(*r_size) + 1; | 379 | 997 | let ents = l_ents + r_ents; | 380 | | | 381 | 997 | if ents <= r_tree.len() { | 382 | | // All entries will fit in the RHS node. | 383 | | // We'll leave the LHS node empty, but first use it as a scratch space. | 384 | 880 | *l_size = 0; | 385 | | // Insert `crit_key` between the two nodes. | 386 | 880 | l_keys[l_ents - 1] = crit_key; | 387 | 880 | l_keys[l_ents..ents - 1].copy_from_slice(&r_keys[0..r_ents - 1]); | 388 | 880 | r_keys[0..ents - 1].copy_from_slice(&l_keys[0..ents - 1]); | 389 | 880 | l_tree[l_ents..ents].copy_from_slice(&r_tree[0..r_ents]); | 390 | 880 | r_tree[0..ents].copy_from_slice(&l_tree[0..ents]); | 391 | 880 | *r_size = (ents - 1) as u8; | 392 | 880 | None | 393 | | } else { | 394 | | // The entries don't all fit in one node. Distribute some from RHS -> LHS. | 395 | | // Split evenly with a bias to putting one entry in LHS. | 396 | 117 | let r_goal = ents / 2; | 397 | 117 | let l_goal = ents - r_goal; | 398 | 117 | debug_assert!(l_goal > l_ents, "Node must be underflowed"); | 399 | | | 400 | 117 | l_keys[l_ents - 1] = crit_key; | 401 | 117 | l_keys[l_ents..l_goal - 1].copy_from_slice(&r_keys[0..l_goal - 1 - l_ents]); | 402 | 117 | l_tree[l_ents..l_goal].copy_from_slice(&r_tree[0..l_goal - l_ents]); | 403 | 117 | *l_size = (l_goal - 1) as u8; | 404 | | | 405 | 117 | let new_crit = r_keys[r_ents - r_goal - 1]; | 406 | 117 | slice_shift(&mut r_keys[0..r_ents - 1], r_ents - r_goal); | 407 | 117 | slice_shift(&mut r_tree[0..r_ents], r_ents - r_goal); | 408 | 117 | *r_size = (r_goal - 1) as u8; | 409 | | | 410 | 117 | Some(new_crit) | 411 | | } | 412 | | } | 413 | | ( | 414 | | &mut Self::Leaf { | 415 | 5.83k | size: ref mut l_size, | 416 | 5.83k | keys: ref mut l_keys, | 417 | 5.83k | vals: ref mut l_vals, | 418 | | }, | 419 | | &mut Self::Leaf { | 420 | 5.83k | size: ref mut r_size, | 421 | 5.83k | keys: ref mut r_keys, | 422 | 5.83k | vals: ref mut r_vals, | 423 | | }, | 424 | | ) => { | 425 | 5.83k | let l_ents = usize::from(*l_size); | 426 | 5.83k | let l_keys = l_keys.borrow_mut(); | 427 | 5.83k | let l_vals = l_vals.borrow_mut(); | 428 | 5.83k | let r_ents = usize::from(*r_size); | 429 | 5.83k | let r_keys = r_keys.borrow_mut(); | 430 | 5.83k | let r_vals = r_vals.borrow_mut(); | 431 | 5.83k | let ents = l_ents + r_ents; | 432 | | | 433 | 5.83k | if ents <= r_vals.len() { | 434 | | // We can fit all entries in the RHS node. | 435 | | // We'll leave the LHS node empty, but first use it as a scratch space. | 436 | 5.16k | *l_size = 0; | 437 | 5.16k | l_keys[l_ents..ents].copy_from_slice(&r_keys[0..r_ents]); | 438 | 5.16k | r_keys[0..ents].copy_from_slice(&l_keys[0..ents]); | 439 | 5.16k | l_vals[l_ents..ents].copy_from_slice(&r_vals[0..r_ents]); | 440 | 5.16k | r_vals[0..ents].copy_from_slice(&l_vals[0..ents]); | 441 | 5.16k | *r_size = ents as u8; | 442 | 5.16k | None | 443 | | } else { | 444 | | // The entries don't all fit in one node. Distribute some from RHS -> LHS. | 445 | | // Split evenly with a bias to putting one entry in LHS. | 446 | 666 | let r_goal = ents / 2; | 447 | 666 | let l_goal = ents - r_goal; | 448 | 666 | debug_assert!(l_goal > l_ents, "Node must be underflowed"); | 449 | | | 450 | 666 | l_keys[l_ents..l_goal].copy_from_slice(&r_keys[0..l_goal - l_ents]); | 451 | 666 | l_vals[l_ents..l_goal].copy_from_slice(&r_vals[0..l_goal - l_ents]); | 452 | 666 | *l_size = l_goal as u8; | 453 | | | 454 | 666 | slice_shift(&mut r_keys[0..r_ents], r_ents - r_goal); | 455 | 666 | slice_shift(&mut r_vals[0..r_ents], r_ents - r_goal); | 456 | 666 | *r_size = r_goal as u8; | 457 | | | 458 | 666 | Some(r_keys[0]) | 459 | | } | 460 | | } | 461 | 0 | _ => panic!("Mismatched nodes"), | 462 | | } | 463 | 6.82k | } |
|
464 | | } |
465 | | |
466 | | /// Find the right split position for halving a full node with `len` entries to recover from a |
467 | | /// failed insertion at `ins`. |
468 | | /// |
469 | | /// If `len` is even, we should split straight down the middle regardless of `len`. |
470 | | /// |
471 | | /// If `len` is odd, we should split the node such that the two halves are the same size after the |
472 | | /// insertion is retried. |
473 | 38.5k | fn split_pos(len: usize, ins: usize) -> usize { |
474 | | // Anticipate `len` being a compile time constant, so this all folds away when `len` is even. |
475 | 38.5k | if ins <= len / 2 { |
476 | 2.91k | len / 2 |
477 | | } else { |
478 | 35.6k | (len + 1) / 2 |
479 | | } |
480 | 38.5k | } |
481 | | |
482 | | /// The result of splitting off the second half of a node. |
483 | | pub(super) struct SplitOff<F: Forest> { |
484 | | /// The number of entries left in the original node which becomes the left-hand-side of the |
485 | | /// pair. This is the number of outgoing node edges for an inner node, and the number of |
486 | | /// key-value pairs for a leaf node. |
487 | | pub lhs_entries: usize, |
488 | | |
489 | | /// The number of entries in the new RHS node. |
490 | | pub rhs_entries: usize, |
491 | | |
492 | | /// The critical key separating the LHS and RHS nodes. All keys in the LHS sub-tree are less |
493 | | /// than the critical key, and all entries in the RHS sub-tree are greater or equal to the |
494 | | /// critical key. |
495 | | pub crit_key: F::Key, |
496 | | |
497 | | /// The RHS node data containing the elements that were removed from the original node (now the |
498 | | /// LHS). |
499 | | pub rhs_data: NodeData<F>, |
500 | | } |
501 | | |
502 | | /// The result of removing an entry from a node. |
503 | | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
504 | | pub(super) enum Removed { |
505 | | /// An entry was removed, and the node is still in good shape. |
506 | | Healthy, |
507 | | |
508 | | /// The node is in good shape after removing the rightmost element. |
509 | | Rightmost, |
510 | | |
511 | | /// The node has too few entries now, and it should be balanced with a sibling node. |
512 | | Underflow, |
513 | | |
514 | | /// The last entry was removed. For an inner node, this means that the `keys` array is empty |
515 | | /// and there is just a single sub-tree left. |
516 | | Empty, |
517 | | } |
518 | | |
519 | | impl Removed { |
520 | | /// Create a `Removed` status from a size and capacity. |
521 | 332k | fn new(removed: usize, new_size: usize, capacity: usize) -> Self { |
522 | 332k | if 2 * new_size >= capacity { |
523 | 21.0k | if removed == new_size { |
524 | 26 | Self::Rightmost |
525 | | } else { |
526 | 21.0k | Self::Healthy |
527 | | } |
528 | 311k | } else if new_size > 0 { |
529 | 77.4k | Self::Underflow |
530 | | } else { |
531 | 234k | Self::Empty |
532 | | } |
533 | 332k | } |
534 | | } |
535 | | |
536 | | // Display ": value" or nothing at all for `()`. |
537 | | pub(super) trait ValDisp { |
538 | | fn valfmt(&self, f: &mut fmt::Formatter) -> fmt::Result; |
539 | | } |
540 | | |
541 | | impl ValDisp for SetValue { |
542 | 0 | fn valfmt(&self, _: &mut fmt::Formatter) -> fmt::Result { |
543 | 0 | Ok(()) |
544 | 0 | } |
545 | | } |
546 | | |
547 | | impl<T: fmt::Display> ValDisp for T { |
548 | 0 | fn valfmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
549 | 0 | write!(f, ":{self}") |
550 | 0 | } |
551 | | } |
552 | | |
553 | | impl<F> fmt::Display for NodeData<F> |
554 | | where |
555 | | F: Forest, |
556 | | F::Key: fmt::Display, |
557 | | F::Value: ValDisp, |
558 | | { |
559 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
560 | 0 | match *self { |
561 | 0 | Self::Inner { size, keys, tree } => { |
562 | 0 | write!(f, "[ {}", tree[0])?; |
563 | 0 | for i in 0..usize::from(size) { |
564 | 0 | write!(f, " {} {}", keys[i], tree[i + 1])?; |
565 | | } |
566 | 0 | write!(f, " ]") |
567 | | } |
568 | 0 | Self::Leaf { size, keys, vals } => { |
569 | 0 | let keys = keys.borrow(); |
570 | 0 | let vals = vals.borrow(); |
571 | 0 | write!(f, "[")?; |
572 | 0 | for i in 0..usize::from(size) { |
573 | 0 | write!(f, " {}", keys[i])?; |
574 | 0 | vals[i].valfmt(f)?; |
575 | | } |
576 | 0 | write!(f, " ]") |
577 | | } |
578 | 0 | Self::Free { next: Some(n) } => write!(f, "[ free -> {n} ]"), |
579 | 0 | Self::Free { next: None } => write!(f, "[ free ]"), |
580 | | } |
581 | 0 | } |
582 | | } |
583 | | |
584 | | #[cfg(test)] |
585 | | mod tests { |
586 | | use super::*; |
587 | | use alloc::string::ToString; |
588 | | use core::mem; |
589 | | |
590 | | // Forest impl for a set implementation. |
591 | | struct TF(); |
592 | | |
593 | | impl Forest for TF { |
594 | | type Key = char; |
595 | | type Value = SetValue; |
596 | | type LeafKeys = [char; 15]; |
597 | | type LeafValues = [SetValue; 15]; |
598 | | |
599 | | fn splat_key(key: Self::Key) -> Self::LeafKeys { |
600 | | [key; 15] |
601 | | } |
602 | | |
603 | | fn splat_value(value: Self::Value) -> Self::LeafValues { |
604 | | [value; 15] |
605 | | } |
606 | | } |
607 | | |
608 | | #[test] |
609 | | fn inner() { |
610 | | let n1 = Node(1); |
611 | | let n2 = Node(2); |
612 | | let n3 = Node(3); |
613 | | let n4 = Node(4); |
614 | | let mut inner = NodeData::<TF>::inner(n1, 'c', n4); |
615 | | assert_eq!(mem::size_of_val(&inner), 64); |
616 | | assert_eq!(inner.to_string(), "[ node1 c node4 ]"); |
617 | | |
618 | | assert!(inner.try_inner_insert(0, 'a', n2)); |
619 | | assert_eq!(inner.to_string(), "[ node1 a node2 c node4 ]"); |
620 | | |
621 | | assert!(inner.try_inner_insert(1, 'b', n3)); |
622 | | assert_eq!(inner.to_string(), "[ node1 a node2 b node3 c node4 ]"); |
623 | | |
624 | | for i in 3..7 { |
625 | | assert!(inner.try_inner_insert( |
626 | | usize::from(i), |
627 | | ('a' as u8 + i) as char, |
628 | | Node(i as u32 + 2), |
629 | | )); |
630 | | } |
631 | | assert_eq!( |
632 | | inner.to_string(), |
633 | | "[ node1 a node2 b node3 c node4 d node5 e node6 f node7 g node8 ]" |
634 | | ); |
635 | | |
636 | | // Now the node is full and insertion should fail anywhere. |
637 | | assert!(!inner.try_inner_insert(0, 'x', n3)); |
638 | | assert!(!inner.try_inner_insert(4, 'x', n3)); |
639 | | assert!(!inner.try_inner_insert(7, 'x', n3)); |
640 | | |
641 | | // Splitting should be independent of the hint because we have an even number of node |
642 | | // references. |
643 | | let saved = inner; |
644 | | let sp = inner.split(1); |
645 | | assert_eq!(sp.lhs_entries, 4); |
646 | | assert_eq!(sp.rhs_entries, 4); |
647 | | assert_eq!(sp.crit_key, 'd'); |
648 | | // The critical key is not present in either of the resulting nodes. |
649 | | assert_eq!(inner.to_string(), "[ node1 a node2 b node3 c node4 ]"); |
650 | | assert_eq!(sp.rhs_data.to_string(), "[ node5 e node6 f node7 g node8 ]"); |
651 | | |
652 | | assert_eq!(inner.inner_remove(0), Removed::Underflow); |
653 | | assert_eq!(inner.to_string(), "[ node2 b node3 c node4 ]"); |
654 | | |
655 | | assert_eq!(inner.inner_remove(1), Removed::Underflow); |
656 | | assert_eq!(inner.to_string(), "[ node2 c node4 ]"); |
657 | | |
658 | | assert_eq!(inner.inner_remove(1), Removed::Underflow); |
659 | | assert_eq!(inner.to_string(), "[ node2 ]"); |
660 | | |
661 | | assert_eq!(inner.inner_remove(0), Removed::Empty); |
662 | | |
663 | | inner = saved; |
664 | | let sp = inner.split(6); |
665 | | assert_eq!(sp.lhs_entries, 4); |
666 | | assert_eq!(sp.rhs_entries, 4); |
667 | | assert_eq!(sp.crit_key, 'd'); |
668 | | assert_eq!(inner.to_string(), "[ node1 a node2 b node3 c node4 ]"); |
669 | | assert_eq!(sp.rhs_data.to_string(), "[ node5 e node6 f node7 g node8 ]"); |
670 | | } |
671 | | |
672 | | #[test] |
673 | | fn leaf() { |
674 | | let mut leaf = NodeData::<TF>::leaf('d', SetValue()); |
675 | | assert_eq!(leaf.to_string(), "[ d ]"); |
676 | | |
677 | | assert!(leaf.try_leaf_insert(0, 'a', SetValue())); |
678 | | assert_eq!(leaf.to_string(), "[ a d ]"); |
679 | | assert!(leaf.try_leaf_insert(1, 'b', SetValue())); |
680 | | assert!(leaf.try_leaf_insert(2, 'c', SetValue())); |
681 | | assert_eq!(leaf.to_string(), "[ a b c d ]"); |
682 | | for i in 4..15 { |
683 | | assert!(leaf.try_leaf_insert(usize::from(i), ('a' as u8 + i) as char, SetValue())); |
684 | | } |
685 | | assert_eq!(leaf.to_string(), "[ a b c d e f g h i j k l m n o ]"); |
686 | | |
687 | | // Now the node is full and insertion should fail anywhere. |
688 | | assert!(!leaf.try_leaf_insert(0, 'x', SetValue())); |
689 | | assert!(!leaf.try_leaf_insert(8, 'x', SetValue())); |
690 | | assert!(!leaf.try_leaf_insert(15, 'x', SetValue())); |
691 | | |
692 | | // The index given to `split` is not the split position, it's a hint for balancing the node. |
693 | | let saved = leaf; |
694 | | let sp = leaf.split(12); |
695 | | assert_eq!(sp.lhs_entries, 8); |
696 | | assert_eq!(sp.rhs_entries, 7); |
697 | | assert_eq!(sp.crit_key, 'i'); |
698 | | assert_eq!(leaf.to_string(), "[ a b c d e f g h ]"); |
699 | | assert_eq!(sp.rhs_data.to_string(), "[ i j k l m n o ]"); |
700 | | |
701 | | assert!(leaf.try_leaf_insert(8, 'i', SetValue())); |
702 | | assert_eq!(leaf.leaf_remove(2), Removed::Healthy); |
703 | | assert_eq!(leaf.to_string(), "[ a b d e f g h i ]"); |
704 | | assert_eq!(leaf.leaf_remove(7), Removed::Underflow); |
705 | | assert_eq!(leaf.to_string(), "[ a b d e f g h ]"); |
706 | | |
707 | | leaf = saved; |
708 | | let sp = leaf.split(7); |
709 | | assert_eq!(sp.lhs_entries, 7); |
710 | | assert_eq!(sp.rhs_entries, 8); |
711 | | assert_eq!(sp.crit_key, 'h'); |
712 | | assert_eq!(leaf.to_string(), "[ a b c d e f g ]"); |
713 | | assert_eq!(sp.rhs_data.to_string(), "[ h i j k l m n o ]"); |
714 | | } |
715 | | |
716 | | #[test] |
717 | | fn optimal_split_pos() { |
718 | | // An even split is easy. |
719 | | assert_eq!(split_pos(8, 0), 4); |
720 | | assert_eq!(split_pos(8, 8), 4); |
721 | | |
722 | | // Easy cases for odd splits. |
723 | | assert_eq!(split_pos(7, 0), 3); |
724 | | assert_eq!(split_pos(7, 7), 4); |
725 | | |
726 | | // If the insertion point is the same as the split position, we |
727 | | // will append to the lhs node. |
728 | | assert_eq!(split_pos(7, 3), 3); |
729 | | assert_eq!(split_pos(7, 4), 4); |
730 | | } |
731 | | |
732 | | #[test] |
733 | | fn inner_balance() { |
734 | | let n1 = Node(1); |
735 | | let n2 = Node(2); |
736 | | let n3 = Node(3); |
737 | | let mut lhs = NodeData::<TF>::inner(n1, 'a', n2); |
738 | | assert!(lhs.try_inner_insert(1, 'b', n3)); |
739 | | assert_eq!(lhs.to_string(), "[ node1 a node2 b node3 ]"); |
740 | | |
741 | | let n11 = Node(11); |
742 | | let n12 = Node(12); |
743 | | let mut rhs = NodeData::<TF>::inner(n11, 'p', n12); |
744 | | |
745 | | for i in 1..4 { |
746 | | assert!(rhs.try_inner_insert( |
747 | | usize::from(i), |
748 | | ('p' as u8 + i) as char, |
749 | | Node(i as u32 + 12), |
750 | | )); |
751 | | } |
752 | | assert_eq!( |
753 | | rhs.to_string(), |
754 | | "[ node11 p node12 q node13 r node14 s node15 ]" |
755 | | ); |
756 | | |
757 | | // 3+5 elements fit in RHS. |
758 | | assert_eq!(lhs.balance('o', &mut rhs), None); |
759 | | assert_eq!( |
760 | | rhs.to_string(), |
761 | | "[ node1 a node2 b node3 o node11 p node12 q node13 r node14 s node15 ]" |
762 | | ); |
763 | | |
764 | | // 2+8 elements are redistributed. |
765 | | lhs = NodeData::<TF>::inner(Node(20), 'x', Node(21)); |
766 | | assert_eq!(lhs.balance('y', &mut rhs), Some('o')); |
767 | | assert_eq!( |
768 | | lhs.to_string(), |
769 | | "[ node20 x node21 y node1 a node2 b node3 ]" |
770 | | ); |
771 | | assert_eq!( |
772 | | rhs.to_string(), |
773 | | "[ node11 p node12 q node13 r node14 s node15 ]" |
774 | | ); |
775 | | } |
776 | | |
777 | | #[test] |
778 | | fn leaf_balance() { |
779 | | let mut lhs = NodeData::<TF>::leaf('a', SetValue()); |
780 | | for i in 1..6 { |
781 | | assert!(lhs.try_leaf_insert(usize::from(i), ('a' as u8 + i) as char, SetValue())); |
782 | | } |
783 | | assert_eq!(lhs.to_string(), "[ a b c d e f ]"); |
784 | | |
785 | | let mut rhs = NodeData::<TF>::leaf('0', SetValue()); |
786 | | for i in 1..8 { |
787 | | assert!(rhs.try_leaf_insert(usize::from(i), ('0' as u8 + i) as char, SetValue())); |
788 | | } |
789 | | assert_eq!(rhs.to_string(), "[ 0 1 2 3 4 5 6 7 ]"); |
790 | | |
791 | | // 6+8 elements all fits in rhs. |
792 | | assert_eq!(lhs.balance('0', &mut rhs), None); |
793 | | assert_eq!(rhs.to_string(), "[ a b c d e f 0 1 2 3 4 5 6 7 ]"); |
794 | | |
795 | | assert!(lhs.try_leaf_insert(0, 'x', SetValue())); |
796 | | assert!(lhs.try_leaf_insert(1, 'y', SetValue())); |
797 | | assert!(lhs.try_leaf_insert(2, 'z', SetValue())); |
798 | | assert_eq!(lhs.to_string(), "[ x y z ]"); |
799 | | |
800 | | // 3+14 elements need redistribution. |
801 | | assert_eq!(lhs.balance('a', &mut rhs), Some('0')); |
802 | | assert_eq!(lhs.to_string(), "[ x y z a b c d e f ]"); |
803 | | assert_eq!(rhs.to_string(), "[ 0 1 2 3 4 5 6 7 ]"); |
804 | | } |
805 | | } |