Coverage Report

Created: 2026-02-14 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}