Coverage Report

Created: 2026-04-09 08:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasmtime/cranelift/bforest/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
1.75M
    pub fn entries(&self) -> usize {
68
1.75M
        match *self {
69
5.35k
            Self::Inner { size, .. } => usize::from(size) + 1,
70
1.75M
            Self::Leaf { size, .. } => usize::from(size),
71
0
            Self::Free { .. } => panic!("freed node"),
72
        }
73
1.75M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::entries
Line
Count
Source
67
792k
    pub fn entries(&self) -> usize {
68
792k
        match *self {
69
0
            Self::Inner { size, .. } => usize::from(size) + 1,
70
792k
            Self::Leaf { size, .. } => usize::from(size),
71
0
            Self::Free { .. } => panic!("freed node"),
72
        }
73
792k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::entries
Line
Count
Source
67
4.03k
    pub fn entries(&self) -> usize {
68
4.03k
        match *self {
69
0
            Self::Inner { size, .. } => usize::from(size) + 1,
70
4.03k
            Self::Leaf { size, .. } => usize::from(size),
71
0
            Self::Free { .. } => panic!("freed node"),
72
        }
73
4.03k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::entries
Line
Count
Source
67
22.9k
    pub fn entries(&self) -> usize {
68
22.9k
        match *self {
69
0
            Self::Inner { size, .. } => usize::from(size) + 1,
70
22.9k
            Self::Leaf { size, .. } => usize::from(size),
71
0
            Self::Free { .. } => panic!("freed node"),
72
        }
73
22.9k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::entries
Line
Count
Source
67
911k
    pub fn entries(&self) -> usize {
68
911k
        match *self {
69
1.19k
            Self::Inner { size, .. } => usize::from(size) + 1,
70
909k
            Self::Leaf { size, .. } => usize::from(size),
71
0
            Self::Free { .. } => panic!("freed node"),
72
        }
73
911k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::entries
Line
Count
Source
67
28.3k
    pub fn entries(&self) -> usize {
68
28.3k
        match *self {
69
4.15k
            Self::Inner { size, .. } => usize::from(size) + 1,
70
24.1k
            Self::Leaf { size, .. } => usize::from(size),
71
0
            Self::Free { .. } => panic!("freed node"),
72
        }
73
28.3k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::entries
74
75
    /// Create an inner node with a single key and two sub-trees.
76
358k
    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
358k
        let mut tree = [right; INNER_SIZE];
80
358k
        tree[0] = left;
81
358k
        Self::Inner {
82
358k
            size: 1,
83
358k
            keys: [key; INNER_SIZE - 1],
84
358k
            tree,
85
358k
        }
86
358k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::inner
Line
Count
Source
76
175
    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
175
        let mut tree = [right; INNER_SIZE];
80
175
        tree[0] = left;
81
175
        Self::Inner {
82
175
            size: 1,
83
175
            keys: [key; INNER_SIZE - 1],
84
175
            tree,
85
175
        }
86
175
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::inner
Line
Count
Source
76
175
    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
175
        let mut tree = [right; INNER_SIZE];
80
175
        tree[0] = left;
81
175
        Self::Inner {
82
175
            size: 1,
83
175
            keys: [key; INNER_SIZE - 1],
84
175
            tree,
85
175
        }
86
175
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::inner
Line
Count
Source
76
860
    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
860
        let mut tree = [right; INNER_SIZE];
80
860
        tree[0] = left;
81
860
        Self::Inner {
82
860
            size: 1,
83
860
            keys: [key; INNER_SIZE - 1],
84
860
            tree,
85
860
        }
86
860
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::inner
Line
Count
Source
76
605
    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
605
        let mut tree = [right; INNER_SIZE];
80
605
        tree[0] = left;
81
605
        Self::Inner {
82
605
            size: 1,
83
605
            keys: [key; INNER_SIZE - 1],
84
605
            tree,
85
605
        }
86
605
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::inner
Line
Count
Source
76
328k
    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
328k
        let mut tree = [right; INNER_SIZE];
80
328k
        tree[0] = left;
81
328k
        Self::Inner {
82
328k
            size: 1,
83
328k
            keys: [key; INNER_SIZE - 1],
84
328k
            tree,
85
328k
        }
86
328k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::inner
Line
Count
Source
76
28.0k
    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.0k
        let mut tree = [right; INNER_SIZE];
80
28.0k
        tree[0] = left;
81
28.0k
        Self::Inner {
82
28.0k
            size: 1,
83
28.0k
            keys: [key; INNER_SIZE - 1],
84
28.0k
            tree,
85
28.0k
        }
86
28.0k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::inner
87
88
    /// Create a leaf node with a single key-value pair.
89
32.4M
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
32.4M
        Self::Leaf {
91
32.4M
            size: 1,
92
32.4M
            keys: F::splat_key(key),
93
32.4M
            vals: F::splat_value(value),
94
32.4M
        }
95
32.4M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::leaf
Line
Count
Source
89
36.4k
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
36.4k
        Self::Leaf {
91
36.4k
            size: 1,
92
36.4k
            keys: F::splat_key(key),
93
36.4k
            vals: F::splat_value(value),
94
36.4k
        }
95
36.4k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::leaf
Line
Count
Source
89
36.4k
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
36.4k
        Self::Leaf {
91
36.4k
            size: 1,
92
36.4k
            keys: F::splat_key(key),
93
36.4k
            vals: F::splat_value(value),
94
36.4k
        }
95
36.4k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::leaf
Line
Count
Source
89
36.2k
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
36.2k
        Self::Leaf {
91
36.2k
            size: 1,
92
36.2k
            keys: F::splat_key(key),
93
36.2k
            vals: F::splat_value(value),
94
36.2k
        }
95
36.2k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::leaf
Line
Count
Source
89
78.8k
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
78.8k
        Self::Leaf {
91
78.8k
            size: 1,
92
78.8k
            keys: F::splat_key(key),
93
78.8k
            vals: F::splat_value(value),
94
78.8k
        }
95
78.8k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf
Line
Count
Source
89
17.0M
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
17.0M
        Self::Leaf {
91
17.0M
            size: 1,
92
17.0M
            keys: F::splat_key(key),
93
17.0M
            vals: F::splat_value(value),
94
17.0M
        }
95
17.0M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::leaf
Line
Count
Source
89
15.2M
    pub fn leaf(key: F::Key, value: F::Value) -> Self {
90
15.2M
        Self::Leaf {
91
15.2M
            size: 1,
92
15.2M
            keys: F::splat_key(key),
93
15.2M
            vals: F::splat_value(value),
94
15.2M
        }
95
15.2M
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::leaf
96
97
    /// Unwrap an inner node into two slices (keys, trees).
98
3.07M
    pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) {
99
3.07M
        match *self {
100
            Self::Inner {
101
3.07M
                size,
102
3.07M
                ref keys,
103
3.07M
                ref tree,
104
            } => {
105
3.07M
                let size = usize::from(size);
106
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
107
                // range.
108
3.07M
                (&keys[0..size], &tree[0..=size])
109
            }
110
0
            _ => panic!("Expected inner node"),
111
        }
112
3.07M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::unwrap_inner
Line
Count
Source
98
58
    pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) {
99
58
        match *self {
100
            Self::Inner {
101
58
                size,
102
58
                ref keys,
103
58
                ref tree,
104
            } => {
105
58
                let size = usize::from(size);
106
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
107
                // range.
108
58
                (&keys[0..size], &tree[0..=size])
109
            }
110
0
            _ => panic!("Expected inner node"),
111
        }
112
58
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::unwrap_inner
Line
Count
Source
98
26
    pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) {
99
26
        match *self {
100
            Self::Inner {
101
26
                size,
102
26
                ref keys,
103
26
                ref tree,
104
            } => {
105
26
                let size = usize::from(size);
106
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
107
                // range.
108
26
                (&keys[0..size], &tree[0..=size])
109
            }
110
0
            _ => panic!("Expected inner node"),
111
        }
112
26
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::unwrap_inner
Line
Count
Source
98
1.23k
    pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) {
99
1.23k
        match *self {
100
            Self::Inner {
101
1.23k
                size,
102
1.23k
                ref keys,
103
1.23k
                ref tree,
104
            } => {
105
1.23k
                let size = usize::from(size);
106
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
107
                // range.
108
1.23k
                (&keys[0..size], &tree[0..=size])
109
            }
110
0
            _ => panic!("Expected inner node"),
111
        }
112
1.23k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::unwrap_inner
Line
Count
Source
98
3.29k
    pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) {
99
3.29k
        match *self {
100
            Self::Inner {
101
3.29k
                size,
102
3.29k
                ref keys,
103
3.29k
                ref tree,
104
            } => {
105
3.29k
                let size = usize::from(size);
106
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
107
                // range.
108
3.29k
                (&keys[0..size], &tree[0..=size])
109
            }
110
0
            _ => panic!("Expected inner node"),
111
        }
112
3.29k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_inner
Line
Count
Source
98
3.07M
    pub fn unwrap_inner(&self) -> (&[F::Key], &[Node]) {
99
3.07M
        match *self {
100
            Self::Inner {
101
3.07M
                size,
102
3.07M
                ref keys,
103
3.07M
                ref tree,
104
            } => {
105
3.07M
                let size = usize::from(size);
106
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
107
                // range.
108
3.07M
                (&keys[0..size], &tree[0..=size])
109
            }
110
0
            _ => panic!("Expected inner node"),
111
        }
112
3.07M
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::unwrap_inner
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::unwrap_inner
113
114
    /// Unwrap a leaf node into two slices (keys, values) of the same length.
115
77.5M
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
77.5M
        match *self {
117
            Self::Leaf {
118
77.5M
                size,
119
77.5M
                ref keys,
120
77.5M
                ref vals,
121
            } => {
122
77.5M
                let size = usize::from(size);
123
77.5M
                let keys = keys.borrow();
124
77.5M
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
77.5M
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
77.5M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::unwrap_leaf
Line
Count
Source
115
10.0M
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
10.0M
        match *self {
117
            Self::Leaf {
118
10.0M
                size,
119
10.0M
                ref keys,
120
10.0M
                ref vals,
121
            } => {
122
10.0M
                let size = usize::from(size);
123
10.0M
                let keys = keys.borrow();
124
10.0M
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
10.0M
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
10.0M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::unwrap_leaf
Line
Count
Source
115
117k
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
117k
        match *self {
117
            Self::Leaf {
118
117k
                size,
119
117k
                ref keys,
120
117k
                ref vals,
121
            } => {
122
117k
                let size = usize::from(size);
123
117k
                let keys = keys.borrow();
124
117k
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
117k
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
117k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::unwrap_leaf
Line
Count
Source
115
82.3k
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
82.3k
        match *self {
117
            Self::Leaf {
118
82.3k
                size,
119
82.3k
                ref keys,
120
82.3k
                ref vals,
121
            } => {
122
82.3k
                let size = usize::from(size);
123
82.3k
                let keys = keys.borrow();
124
82.3k
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
82.3k
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
82.3k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::unwrap_leaf
Line
Count
Source
115
1.05M
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
1.05M
        match *self {
117
            Self::Leaf {
118
1.05M
                size,
119
1.05M
                ref keys,
120
1.05M
                ref vals,
121
            } => {
122
1.05M
                let size = usize::from(size);
123
1.05M
                let keys = keys.borrow();
124
1.05M
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
1.05M
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
1.05M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::unwrap_leaf
Line
Count
Source
115
56.5M
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
56.5M
        match *self {
117
            Self::Leaf {
118
56.5M
                size,
119
56.5M
                ref keys,
120
56.5M
                ref vals,
121
            } => {
122
56.5M
                let size = usize::from(size);
123
56.5M
                let keys = keys.borrow();
124
56.5M
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
56.5M
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
56.5M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::unwrap_leaf
Line
Count
Source
115
9.71M
    pub fn unwrap_leaf(&self) -> (&[F::Key], &[F::Value]) {
116
9.71M
        match *self {
117
            Self::Leaf {
118
9.71M
                size,
119
9.71M
                ref keys,
120
9.71M
                ref vals,
121
            } => {
122
9.71M
                let size = usize::from(size);
123
9.71M
                let keys = keys.borrow();
124
9.71M
                let vals = vals.borrow();
125
                // TODO: We could probably use `get_unchecked()` here since `size` is always in
126
                // range.
127
9.71M
                (&keys[0..size], &vals[0..size])
128
            }
129
0
            _ => panic!("Expected leaf node"),
130
        }
131
9.71M
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::unwrap_leaf
132
133
    /// Unwrap a mutable leaf node into two slices (keys, values) of the same length.
134
16.3M
    pub fn unwrap_leaf_mut(&mut self) -> (&mut [F::Key], &mut [F::Value]) {
135
16.3M
        match *self {
136
            Self::Leaf {
137
16.3M
                size,
138
16.3M
                ref mut keys,
139
16.3M
                ref mut vals,
140
            } => {
141
16.3M
                let size = usize::from(size);
142
16.3M
                let keys = keys.borrow_mut();
143
16.3M
                let vals = vals.borrow_mut();
144
                // TODO: We could probably use `get_unchecked_mut()` here since `size` is always in
145
                // range.
146
16.3M
                (&mut keys[0..size], &mut vals[0..size])
147
            }
148
0
            _ => panic!("Expected leaf node"),
149
        }
150
16.3M
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::unwrap_leaf_mut
Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::unwrap_leaf_mut
Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::unwrap_leaf_mut
Unexecuted instantiation: <cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::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
16.3M
    pub fn unwrap_leaf_mut(&mut self) -> (&mut [F::Key], &mut [F::Value]) {
135
16.3M
        match *self {
136
            Self::Leaf {
137
16.3M
                size,
138
16.3M
                ref mut keys,
139
16.3M
                ref mut vals,
140
            } => {
141
16.3M
                let size = usize::from(size);
142
16.3M
                let keys = keys.borrow_mut();
143
16.3M
                let vals = vals.borrow_mut();
144
                // TODO: We could probably use `get_unchecked_mut()` here since `size` is always in
145
                // range.
146
16.3M
                (&mut keys[0..size], &mut vals[0..size])
147
            }
148
0
            _ => panic!("Expected leaf node"),
149
        }
150
16.3M
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::unwrap_leaf_mut
151
152
    /// Get the critical key for a leaf node.
153
    /// This is simply the first key.
154
914
    pub fn leaf_crit_key(&self) -> F::Key {
155
914
        match *self {
156
914
            Self::Leaf { size, ref keys, .. } => {
157
914
                debug_assert!(size > 0, "Empty leaf node");
158
914
                keys.borrow()[0]
159
            }
160
0
            _ => panic!("Expected leaf node"),
161
        }
162
914
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::leaf_crit_key
Line
Count
Source
154
619
    pub fn leaf_crit_key(&self) -> F::Key {
155
619
        match *self {
156
619
            Self::Leaf { size, ref keys, .. } => {
157
619
                debug_assert!(size > 0, "Empty leaf node");
158
619
                keys.borrow()[0]
159
            }
160
0
            _ => panic!("Expected leaf node"),
161
        }
162
619
    }
<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
295
    pub fn leaf_crit_key(&self) -> F::Key {
155
295
        match *self {
156
295
            Self::Leaf { size, ref keys, .. } => {
157
295
                debug_assert!(size > 0, "Empty leaf node");
158
295
                keys.borrow()[0]
159
            }
160
0
            _ => panic!("Expected leaf node"),
161
        }
162
295
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::leaf_crit_key
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
1.07M
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
1.07M
        match *self {
169
            Self::Inner {
170
1.07M
                ref mut size,
171
1.07M
                ref mut keys,
172
1.07M
                ref mut tree,
173
            } => {
174
1.07M
                let sz = usize::from(*size);
175
1.07M
                debug_assert!(sz <= keys.len());
176
1.07M
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
1.07M
                if let Some(ks) = keys.get_mut(0..=sz) {
179
977k
                    *size = (sz + 1) as u8;
180
977k
                    slice_insert(ks, index, key);
181
977k
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
977k
                    true
183
                } else {
184
96.7k
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
1.07M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::try_inner_insert
Line
Count
Source
167
469
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
469
        match *self {
169
            Self::Inner {
170
469
                ref mut size,
171
469
                ref mut keys,
172
469
                ref mut tree,
173
            } => {
174
469
                let sz = usize::from(*size);
175
469
                debug_assert!(sz <= keys.len());
176
469
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
469
                if let Some(ks) = keys.get_mut(0..=sz) {
179
419
                    *size = (sz + 1) as u8;
180
419
                    slice_insert(ks, index, key);
181
419
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
419
                    true
183
                } else {
184
50
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
469
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::try_inner_insert
Line
Count
Source
167
469
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
469
        match *self {
169
            Self::Inner {
170
469
                ref mut size,
171
469
                ref mut keys,
172
469
                ref mut tree,
173
            } => {
174
469
                let sz = usize::from(*size);
175
469
                debug_assert!(sz <= keys.len());
176
469
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
469
                if let Some(ks) = keys.get_mut(0..=sz) {
179
419
                    *size = (sz + 1) as u8;
180
419
                    slice_insert(ks, index, key);
181
419
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
419
                    true
183
                } else {
184
50
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
469
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::try_inner_insert
Line
Count
Source
167
471
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
471
        match *self {
169
            Self::Inner {
170
471
                ref mut size,
171
471
                ref mut keys,
172
471
                ref mut tree,
173
            } => {
174
471
                let sz = usize::from(*size);
175
471
                debug_assert!(sz <= keys.len());
176
471
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
471
                if let Some(ks) = keys.get_mut(0..=sz) {
179
421
                    *size = (sz + 1) as u8;
180
421
                    slice_insert(ks, index, key);
181
421
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
421
                    true
183
                } else {
184
50
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
471
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::try_inner_insert
Line
Count
Source
167
1.01k
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
1.01k
        match *self {
169
            Self::Inner {
170
1.01k
                ref mut size,
171
1.01k
                ref mut keys,
172
1.01k
                ref mut tree,
173
            } => {
174
1.01k
                let sz = usize::from(*size);
175
1.01k
                debug_assert!(sz <= keys.len());
176
1.01k
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
1.01k
                if let Some(ks) = keys.get_mut(0..=sz) {
179
961
                    *size = (sz + 1) as u8;
180
961
                    slice_insert(ks, index, key);
181
961
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
961
                    true
183
                } else {
184
52
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
1.01k
    }
<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
1.04M
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
1.04M
        match *self {
169
            Self::Inner {
170
1.04M
                ref mut size,
171
1.04M
                ref mut keys,
172
1.04M
                ref mut tree,
173
            } => {
174
1.04M
                let sz = usize::from(*size);
175
1.04M
                debug_assert!(sz <= keys.len());
176
1.04M
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
1.04M
                if let Some(ks) = keys.get_mut(0..=sz) {
179
949k
                    *size = (sz + 1) as u8;
180
949k
                    slice_insert(ks, index, key);
181
949k
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
949k
                    true
183
                } else {
184
96.1k
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
1.04M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::try_inner_insert
Line
Count
Source
167
26.2k
    pub fn try_inner_insert(&mut self, index: usize, key: F::Key, node: Node) -> bool {
168
26.2k
        match *self {
169
            Self::Inner {
170
26.2k
                ref mut size,
171
26.2k
                ref mut keys,
172
26.2k
                ref mut tree,
173
            } => {
174
26.2k
                let sz = usize::from(*size);
175
26.2k
                debug_assert!(sz <= keys.len());
176
26.2k
                debug_assert!(index <= sz, "Can't insert at {index} with {sz} keys");
177
178
26.2k
                if let Some(ks) = keys.get_mut(0..=sz) {
179
25.8k
                    *size = (sz + 1) as u8;
180
25.8k
                    slice_insert(ks, index, key);
181
25.8k
                    slice_insert(&mut tree[1..=sz + 1], index, node);
182
25.8k
                    true
183
                } else {
184
390
                    false
185
                }
186
            }
187
0
            _ => panic!("Expected inner node"),
188
        }
189
26.2k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::try_inner_insert
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
22.5M
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
22.5M
        match *self {
195
            Self::Leaf {
196
22.5M
                ref mut size,
197
22.5M
                ref mut keys,
198
22.5M
                ref mut vals,
199
            } => {
200
22.5M
                let sz = usize::from(*size);
201
22.5M
                let keys = keys.borrow_mut();
202
22.5M
                let vals = vals.borrow_mut();
203
22.5M
                debug_assert!(sz <= keys.len());
204
22.5M
                debug_assert!(index <= sz);
205
206
22.5M
                if let Some(ks) = keys.get_mut(0..=sz) {
207
21.3M
                    *size = (sz + 1) as u8;
208
21.3M
                    slice_insert(ks, index, key);
209
21.3M
                    slice_insert(&mut vals[0..=sz], index, value);
210
21.3M
                    true
211
                } else {
212
1.23M
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
22.5M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::try_leaf_insert
Line
Count
Source
193
4.58k
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
4.58k
        match *self {
195
            Self::Leaf {
196
4.58k
                ref mut size,
197
4.58k
                ref mut keys,
198
4.58k
                ref mut vals,
199
            } => {
200
4.58k
                let sz = usize::from(*size);
201
4.58k
                let keys = keys.borrow_mut();
202
4.58k
                let vals = vals.borrow_mut();
203
4.58k
                debug_assert!(sz <= keys.len());
204
4.58k
                debug_assert!(index <= sz);
205
206
4.58k
                if let Some(ks) = keys.get_mut(0..=sz) {
207
4.03k
                    *size = (sz + 1) as u8;
208
4.03k
                    slice_insert(ks, index, key);
209
4.03k
                    slice_insert(&mut vals[0..=sz], index, value);
210
4.03k
                    true
211
                } else {
212
544
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
4.58k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::try_leaf_insert
Line
Count
Source
193
4.58k
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
4.58k
        match *self {
195
            Self::Leaf {
196
4.58k
                ref mut size,
197
4.58k
                ref mut keys,
198
4.58k
                ref mut vals,
199
            } => {
200
4.58k
                let sz = usize::from(*size);
201
4.58k
                let keys = keys.borrow_mut();
202
4.58k
                let vals = vals.borrow_mut();
203
4.58k
                debug_assert!(sz <= keys.len());
204
4.58k
                debug_assert!(index <= sz);
205
206
4.58k
                if let Some(ks) = keys.get_mut(0..=sz) {
207
4.03k
                    *size = (sz + 1) as u8;
208
4.03k
                    slice_insert(ks, index, key);
209
4.03k
                    slice_insert(&mut vals[0..=sz], index, value);
210
4.03k
                    true
211
                } else {
212
544
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
4.58k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::try_leaf_insert
Line
Count
Source
193
24.1k
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
24.1k
        match *self {
195
            Self::Leaf {
196
24.1k
                ref mut size,
197
24.1k
                ref mut keys,
198
24.1k
                ref mut vals,
199
            } => {
200
24.1k
                let sz = usize::from(*size);
201
24.1k
                let keys = keys.borrow_mut();
202
24.1k
                let vals = vals.borrow_mut();
203
24.1k
                debug_assert!(sz <= keys.len());
204
24.1k
                debug_assert!(index <= sz);
205
206
24.1k
                if let Some(ks) = keys.get_mut(0..=sz) {
207
22.9k
                    *size = (sz + 1) as u8;
208
22.9k
                    slice_insert(ks, index, key);
209
22.9k
                    slice_insert(&mut vals[0..=sz], index, value);
210
22.9k
                    true
211
                } else {
212
1.23k
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
24.1k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::try_leaf_insert
Line
Count
Source
193
50.4k
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
50.4k
        match *self {
195
            Self::Leaf {
196
50.4k
                ref mut size,
197
50.4k
                ref mut keys,
198
50.4k
                ref mut vals,
199
            } => {
200
50.4k
                let sz = usize::from(*size);
201
50.4k
                let keys = keys.borrow_mut();
202
50.4k
                let vals = vals.borrow_mut();
203
50.4k
                debug_assert!(sz <= keys.len());
204
50.4k
                debug_assert!(index <= sz);
205
206
50.4k
                if let Some(ks) = keys.get_mut(0..=sz) {
207
48.9k
                    *size = (sz + 1) as u8;
208
48.9k
                    slice_insert(ks, index, key);
209
48.9k
                    slice_insert(&mut vals[0..=sz], index, value);
210
48.9k
                    true
211
                } else {
212
1.51k
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
50.4k
    }
<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
10.9M
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
10.9M
        match *self {
195
            Self::Leaf {
196
10.9M
                ref mut size,
197
10.9M
                ref mut keys,
198
10.9M
                ref mut vals,
199
            } => {
200
10.9M
                let sz = usize::from(*size);
201
10.9M
                let keys = keys.borrow_mut();
202
10.9M
                let vals = vals.borrow_mut();
203
10.9M
                debug_assert!(sz <= keys.len());
204
10.9M
                debug_assert!(index <= sz);
205
206
10.9M
                if let Some(ks) = keys.get_mut(0..=sz) {
207
9.75M
                    *size = (sz + 1) as u8;
208
9.75M
                    slice_insert(ks, index, key);
209
9.75M
                    slice_insert(&mut vals[0..=sz], index, value);
210
9.75M
                    true
211
                } else {
212
1.18M
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
10.9M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::try_leaf_insert
Line
Count
Source
193
11.5M
    pub fn try_leaf_insert(&mut self, index: usize, key: F::Key, value: F::Value) -> bool {
194
11.5M
        match *self {
195
            Self::Leaf {
196
11.5M
                ref mut size,
197
11.5M
                ref mut keys,
198
11.5M
                ref mut vals,
199
            } => {
200
11.5M
                let sz = usize::from(*size);
201
11.5M
                let keys = keys.borrow_mut();
202
11.5M
                let vals = vals.borrow_mut();
203
11.5M
                debug_assert!(sz <= keys.len());
204
11.5M
                debug_assert!(index <= sz);
205
206
11.5M
                if let Some(ks) = keys.get_mut(0..=sz) {
207
11.4M
                    *size = (sz + 1) as u8;
208
11.4M
                    slice_insert(ks, index, key);
209
11.4M
                    slice_insert(&mut vals[0..=sz], index, value);
210
11.4M
                    true
211
                } else {
212
53.5k
                    false
213
                }
214
            }
215
0
            _ => panic!("Expected leaf node"),
216
        }
217
11.5M
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::try_leaf_insert
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
1.33M
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
1.33M
        match *self {
226
            Self::Inner {
227
96.7k
                ref mut size,
228
96.7k
                ref keys,
229
96.7k
                ref tree,
230
            } => {
231
96.7k
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
96.7k
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
96.7k
                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
96.7k
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
96.7k
                let mut r_keys = *keys;
249
96.7k
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
96.7k
                let mut r_tree = *tree;
252
96.7k
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
96.7k
                SplitOff {
255
96.7k
                    lhs_entries: l_ents,
256
96.7k
                    rhs_entries: r_ents,
257
96.7k
                    crit_key: keys[l_ents - 1],
258
96.7k
                    rhs_data: Self::Inner {
259
96.7k
                        size: (r_ents - 1) as u8,
260
96.7k
                        keys: r_keys,
261
96.7k
                        tree: r_tree,
262
96.7k
                    },
263
96.7k
                }
264
            }
265
            Self::Leaf {
266
1.23M
                ref mut size,
267
1.23M
                ref keys,
268
1.23M
                ref vals,
269
            } => {
270
1.23M
                let o_keys = keys.borrow();
271
1.23M
                let o_vals = vals.borrow();
272
1.23M
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
1.23M
                let l_size = split_pos(o_keys.len(), insert_index);
275
1.23M
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
1.23M
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
1.23M
                let mut r_keys = *keys;
282
1.23M
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
1.23M
                let mut r_vals = *vals;
285
1.23M
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
1.23M
                SplitOff {
288
1.23M
                    lhs_entries: l_size,
289
1.23M
                    rhs_entries: r_size,
290
1.23M
                    crit_key: o_keys[l_size],
291
1.23M
                    rhs_data: Self::Leaf {
292
1.23M
                        size: r_size as u8,
293
1.23M
                        keys: r_keys,
294
1.23M
                        vals: r_vals,
295
1.23M
                    },
296
1.23M
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
1.33M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::StoreCodePC, wasmtime_internal_core::slab::Id>>>::split
Line
Count
Source
224
594
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
594
        match *self {
226
            Self::Inner {
227
50
                ref mut size,
228
50
                ref keys,
229
50
                ref tree,
230
            } => {
231
50
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
50
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
50
                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
50
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
50
                let mut r_keys = *keys;
249
50
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
50
                let mut r_tree = *tree;
252
50
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
50
                SplitOff {
255
50
                    lhs_entries: l_ents,
256
50
                    rhs_entries: r_ents,
257
50
                    crit_key: keys[l_ents - 1],
258
50
                    rhs_data: Self::Inner {
259
50
                        size: (r_ents - 1) as u8,
260
50
                        keys: r_keys,
261
50
                        tree: r_tree,
262
50
                    },
263
50
                }
264
            }
265
            Self::Leaf {
266
544
                ref mut size,
267
544
                ref keys,
268
544
                ref vals,
269
            } => {
270
544
                let o_keys = keys.borrow();
271
544
                let o_vals = vals.borrow();
272
544
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
544
                let l_size = split_pos(o_keys.len(), insert_index);
275
544
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
544
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
544
                let mut r_keys = *keys;
282
544
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
544
                let mut r_vals = *vals;
285
544
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
544
                SplitOff {
288
544
                    lhs_entries: l_size,
289
544
                    rhs_entries: r_size,
290
544
                    crit_key: o_keys[l_size],
291
544
                    rhs_data: Self::Leaf {
292
544
                        size: r_size as u8,
293
544
                        keys: r_keys,
294
544
                        vals: r_vals,
295
544
                    },
296
544
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
594
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::code::EngineCodePC, wasmtime_internal_core::slab::Id>>>::split
Line
Count
Source
224
594
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
594
        match *self {
226
            Self::Inner {
227
50
                ref mut size,
228
50
                ref keys,
229
50
                ref tree,
230
            } => {
231
50
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
50
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
50
                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
50
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
50
                let mut r_keys = *keys;
249
50
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
50
                let mut r_tree = *tree;
252
50
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
50
                SplitOff {
255
50
                    lhs_entries: l_ents,
256
50
                    rhs_entries: r_ents,
257
50
                    crit_key: keys[l_ents - 1],
258
50
                    rhs_data: Self::Inner {
259
50
                        size: (r_ents - 1) as u8,
260
50
                        keys: r_keys,
261
50
                        tree: r_tree,
262
50
                    },
263
50
                }
264
            }
265
            Self::Leaf {
266
544
                ref mut size,
267
544
                ref keys,
268
544
                ref vals,
269
            } => {
270
544
                let o_keys = keys.borrow();
271
544
                let o_vals = vals.borrow();
272
544
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
544
                let l_size = split_pos(o_keys.len(), insert_index);
275
544
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
544
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
544
                let mut r_keys = *keys;
282
544
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
544
                let mut r_vals = *vals;
285
544
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
544
                SplitOff {
288
544
                    lhs_entries: l_size,
289
544
                    rhs_entries: r_size,
290
544
                    crit_key: o_keys[l_size],
291
544
                    rhs_data: Self::Leaf {
292
544
                        size: r_size as u8,
293
544
                        keys: r_keys,
294
544
                        vals: r_vals,
295
544
                    },
296
544
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
594
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<wasmtime::runtime::module::registry::RegisteredModuleId, wasmtime_internal_core::slab::Id>>>::split
Line
Count
Source
224
1.28k
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
1.28k
        match *self {
226
            Self::Inner {
227
50
                ref mut size,
228
50
                ref keys,
229
50
                ref tree,
230
            } => {
231
50
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
50
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
50
                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
50
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
50
                let mut r_keys = *keys;
249
50
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
50
                let mut r_tree = *tree;
252
50
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
50
                SplitOff {
255
50
                    lhs_entries: l_ents,
256
50
                    rhs_entries: r_ents,
257
50
                    crit_key: keys[l_ents - 1],
258
50
                    rhs_data: Self::Inner {
259
50
                        size: (r_ents - 1) as u8,
260
50
                        keys: r_keys,
261
50
                        tree: r_tree,
262
50
                    },
263
50
                }
264
            }
265
            Self::Leaf {
266
1.23k
                ref mut size,
267
1.23k
                ref keys,
268
1.23k
                ref vals,
269
            } => {
270
1.23k
                let o_keys = keys.borrow();
271
1.23k
                let o_vals = vals.borrow();
272
1.23k
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
1.23k
                let l_size = split_pos(o_keys.len(), insert_index);
275
1.23k
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
1.23k
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
1.23k
                let mut r_keys = *keys;
282
1.23k
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
1.23k
                let mut r_vals = *vals;
285
1.23k
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
1.23k
                SplitOff {
288
1.23k
                    lhs_entries: l_size,
289
1.23k
                    rhs_entries: r_size,
290
1.23k
                    crit_key: o_keys[l_size],
291
1.23k
                    rhs_data: Self::Leaf {
292
1.23k
                        size: r_size as u8,
293
1.23k
                        keys: r_keys,
294
1.23k
                        vals: r_vals,
295
1.23k
                    },
296
1.23k
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
1.28k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::split
Line
Count
Source
224
1.56k
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
1.56k
        match *self {
226
            Self::Inner {
227
52
                ref mut size,
228
52
                ref keys,
229
52
                ref tree,
230
            } => {
231
52
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
52
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
52
                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
52
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
52
                let mut r_keys = *keys;
249
52
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
52
                let mut r_tree = *tree;
252
52
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
52
                SplitOff {
255
52
                    lhs_entries: l_ents,
256
52
                    rhs_entries: r_ents,
257
52
                    crit_key: keys[l_ents - 1],
258
52
                    rhs_data: Self::Inner {
259
52
                        size: (r_ents - 1) as u8,
260
52
                        keys: r_keys,
261
52
                        tree: r_tree,
262
52
                    },
263
52
                }
264
            }
265
            Self::Leaf {
266
1.51k
                ref mut size,
267
1.51k
                ref keys,
268
1.51k
                ref vals,
269
            } => {
270
1.51k
                let o_keys = keys.borrow();
271
1.51k
                let o_vals = vals.borrow();
272
1.51k
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
1.51k
                let l_size = split_pos(o_keys.len(), insert_index);
275
1.51k
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
1.51k
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
1.51k
                let mut r_keys = *keys;
282
1.51k
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
1.51k
                let mut r_vals = *vals;
285
1.51k
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
1.51k
                SplitOff {
288
1.51k
                    lhs_entries: l_size,
289
1.51k
                    rhs_entries: r_size,
290
1.51k
                    crit_key: o_keys[l_size],
291
1.51k
                    rhs_data: Self::Leaf {
292
1.51k
                        size: r_size as u8,
293
1.51k
                        keys: r_keys,
294
1.51k
                        vals: r_vals,
295
1.51k
                    },
296
1.51k
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
1.56k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::split
Line
Count
Source
224
1.27M
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
1.27M
        match *self {
226
            Self::Inner {
227
96.1k
                ref mut size,
228
96.1k
                ref keys,
229
96.1k
                ref tree,
230
            } => {
231
96.1k
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
96.1k
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
96.1k
                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
96.1k
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
96.1k
                let mut r_keys = *keys;
249
96.1k
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
96.1k
                let mut r_tree = *tree;
252
96.1k
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
96.1k
                SplitOff {
255
96.1k
                    lhs_entries: l_ents,
256
96.1k
                    rhs_entries: r_ents,
257
96.1k
                    crit_key: keys[l_ents - 1],
258
96.1k
                    rhs_data: Self::Inner {
259
96.1k
                        size: (r_ents - 1) as u8,
260
96.1k
                        keys: r_keys,
261
96.1k
                        tree: r_tree,
262
96.1k
                    },
263
96.1k
                }
264
            }
265
            Self::Leaf {
266
1.18M
                ref mut size,
267
1.18M
                ref keys,
268
1.18M
                ref vals,
269
            } => {
270
1.18M
                let o_keys = keys.borrow();
271
1.18M
                let o_vals = vals.borrow();
272
1.18M
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
1.18M
                let l_size = split_pos(o_keys.len(), insert_index);
275
1.18M
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
1.18M
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
1.18M
                let mut r_keys = *keys;
282
1.18M
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
1.18M
                let mut r_vals = *vals;
285
1.18M
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
1.18M
                SplitOff {
288
1.18M
                    lhs_entries: l_size,
289
1.18M
                    rhs_entries: r_size,
290
1.18M
                    crit_key: o_keys[l_size],
291
1.18M
                    rhs_data: Self::Leaf {
292
1.18M
                        size: r_size as u8,
293
1.18M
                        keys: r_keys,
294
1.18M
                        vals: r_vals,
295
1.18M
                    },
296
1.18M
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
1.27M
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::set::SetTypes<cranelift_codegen::ir::entities::Block>>>::split
Line
Count
Source
224
53.9k
    pub fn split(&mut self, insert_index: usize) -> SplitOff<F> {
225
53.9k
        match *self {
226
            Self::Inner {
227
390
                ref mut size,
228
390
                ref keys,
229
390
                ref tree,
230
            } => {
231
390
                debug_assert_eq!(usize::from(*size), keys.len(), "Node not full");
232
233
                // Number of tree entries in the lhs node.
234
390
                let l_ents = split_pos(tree.len(), insert_index + 1);
235
390
                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
390
                *size = (l_ents - 1) as u8;
246
247
                // 2. Copy second half to `rhs_data`.
248
390
                let mut r_keys = *keys;
249
390
                r_keys[0..r_ents - 1].copy_from_slice(&keys[l_ents..]);
250
251
390
                let mut r_tree = *tree;
252
390
                r_tree[0..r_ents].copy_from_slice(&tree[l_ents..]);
253
254
390
                SplitOff {
255
390
                    lhs_entries: l_ents,
256
390
                    rhs_entries: r_ents,
257
390
                    crit_key: keys[l_ents - 1],
258
390
                    rhs_data: Self::Inner {
259
390
                        size: (r_ents - 1) as u8,
260
390
                        keys: r_keys,
261
390
                        tree: r_tree,
262
390
                    },
263
390
                }
264
            }
265
            Self::Leaf {
266
53.5k
                ref mut size,
267
53.5k
                ref keys,
268
53.5k
                ref vals,
269
            } => {
270
53.5k
                let o_keys = keys.borrow();
271
53.5k
                let o_vals = vals.borrow();
272
53.5k
                debug_assert_eq!(usize::from(*size), o_keys.len(), "Node not full");
273
274
53.5k
                let l_size = split_pos(o_keys.len(), insert_index);
275
53.5k
                let r_size = o_keys.len() - l_size;
276
277
                // 1. Truncate the LHS node at `l_size`.
278
53.5k
                *size = l_size as u8;
279
280
                // 2. Copy second half to `rhs_data`.
281
53.5k
                let mut r_keys = *keys;
282
53.5k
                r_keys.borrow_mut()[0..r_size].copy_from_slice(&o_keys[l_size..]);
283
284
53.5k
                let mut r_vals = *vals;
285
53.5k
                r_vals.borrow_mut()[0..r_size].copy_from_slice(&o_vals[l_size..]);
286
287
53.5k
                SplitOff {
288
53.5k
                    lhs_entries: l_size,
289
53.5k
                    rhs_entries: r_size,
290
53.5k
                    crit_key: o_keys[l_size],
291
53.5k
                    rhs_data: Self::Leaf {
292
53.5k
                        size: r_size as u8,
293
53.5k
                        keys: r_keys,
294
53.5k
                        vals: r_vals,
295
53.5k
                    },
296
53.5k
                }
297
            }
298
0
            _ => panic!("Expected leaf node"),
299
        }
300
53.9k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::split
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
11.5k
    pub fn inner_remove(&mut self, index: usize) -> Removed {
310
11.5k
        match *self {
311
            Self::Inner {
312
11.5k
                ref mut size,
313
11.5k
                ref mut keys,
314
11.5k
                ref mut tree,
315
            } => {
316
11.5k
                let ents = usize::from(*size) + 1;
317
11.5k
                debug_assert!(ents <= tree.len());
318
11.5k
                debug_assert!(index < ents);
319
                // Leave an invalid 0xff size when node becomes empty.
320
11.5k
                *size = ents.wrapping_sub(2) as u8;
321
11.5k
                if ents > 1 {
322
11.4k
                    slice_shift(&mut keys[index.saturating_sub(1)..ents - 1], 1);
323
11.4k
                }
324
11.5k
                slice_shift(&mut tree[index..ents], 1);
325
11.5k
                Removed::new(index, ents - 1, tree.len())
326
            }
327
0
            _ => panic!("Expected inner node"),
328
        }
329
11.5k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::inner_remove
Line
Count
Source
309
1.51k
    pub fn inner_remove(&mut self, index: usize) -> Removed {
310
1.51k
        match *self {
311
            Self::Inner {
312
1.51k
                ref mut size,
313
1.51k
                ref mut keys,
314
1.51k
                ref mut tree,
315
            } => {
316
1.51k
                let ents = usize::from(*size) + 1;
317
1.51k
                debug_assert!(ents <= tree.len());
318
1.51k
                debug_assert!(index < ents);
319
                // Leave an invalid 0xff size when node becomes empty.
320
1.51k
                *size = ents.wrapping_sub(2) as u8;
321
1.51k
                if ents > 1 {
322
1.47k
                    slice_shift(&mut keys[index.saturating_sub(1)..ents - 1], 1);
323
1.47k
                }
324
1.51k
                slice_shift(&mut tree[index..ents], 1);
325
1.51k
                Removed::new(index, ents - 1, tree.len())
326
            }
327
0
            _ => panic!("Expected inner node"),
328
        }
329
1.51k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::inner_remove
Line
Count
Source
309
10.0k
    pub fn inner_remove(&mut self, index: usize) -> Removed {
310
10.0k
        match *self {
311
            Self::Inner {
312
10.0k
                ref mut size,
313
10.0k
                ref mut keys,
314
10.0k
                ref mut tree,
315
            } => {
316
10.0k
                let ents = usize::from(*size) + 1;
317
10.0k
                debug_assert!(ents <= tree.len());
318
10.0k
                debug_assert!(index < ents);
319
                // Leave an invalid 0xff size when node becomes empty.
320
10.0k
                *size = ents.wrapping_sub(2) as u8;
321
10.0k
                if ents > 1 {
322
10.0k
                    slice_shift(&mut keys[index.saturating_sub(1)..ents - 1], 1);
323
10.0k
                }
324
10.0k
                slice_shift(&mut tree[index..ents], 1);
325
10.0k
                Removed::new(index, ents - 1, tree.len())
326
            }
327
0
            _ => panic!("Expected inner node"),
328
        }
329
10.0k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::inner_remove
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
153k
    pub fn leaf_remove(&mut self, index: usize) -> Removed {
335
153k
        match *self {
336
            Self::Leaf {
337
153k
                ref mut size,
338
153k
                ref mut keys,
339
153k
                ref mut vals,
340
            } => {
341
153k
                let sz = usize::from(*size);
342
153k
                let keys = keys.borrow_mut();
343
153k
                let vals = vals.borrow_mut();
344
153k
                *size -= 1;
345
153k
                slice_shift(&mut keys[index..sz], 1);
346
153k
                slice_shift(&mut vals[index..sz], 1);
347
153k
                Removed::new(index, sz - 1, keys.len())
348
            }
349
0
            _ => panic!("Expected leaf node"),
350
        }
351
153k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::leaf_remove
Line
Count
Source
334
73.2k
    pub fn leaf_remove(&mut self, index: usize) -> Removed {
335
73.2k
        match *self {
336
            Self::Leaf {
337
73.2k
                ref mut size,
338
73.2k
                ref mut keys,
339
73.2k
                ref mut vals,
340
            } => {
341
73.2k
                let sz = usize::from(*size);
342
73.2k
                let keys = keys.borrow_mut();
343
73.2k
                let vals = vals.borrow_mut();
344
73.2k
                *size -= 1;
345
73.2k
                slice_shift(&mut keys[index..sz], 1);
346
73.2k
                slice_shift(&mut vals[index..sz], 1);
347
73.2k
                Removed::new(index, sz - 1, keys.len())
348
            }
349
0
            _ => panic!("Expected leaf node"),
350
        }
351
73.2k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::leaf_remove
Line
Count
Source
334
80.1k
    pub fn leaf_remove(&mut self, index: usize) -> Removed {
335
80.1k
        match *self {
336
            Self::Leaf {
337
80.1k
                ref mut size,
338
80.1k
                ref mut keys,
339
80.1k
                ref mut vals,
340
            } => {
341
80.1k
                let sz = usize::from(*size);
342
80.1k
                let keys = keys.borrow_mut();
343
80.1k
                let vals = vals.borrow_mut();
344
80.1k
                *size -= 1;
345
80.1k
                slice_shift(&mut keys[index..sz], 1);
346
80.1k
                slice_shift(&mut vals[index..sz], 1);
347
80.1k
                Removed::new(index, sz - 1, keys.len())
348
            }
349
0
            _ => panic!("Expected leaf node"),
350
        }
351
80.1k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::leaf_remove
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
14.2k
    pub fn balance(&mut self, crit_key: F::Key, rhs: &mut Self) -> Option<F::Key> {
364
14.2k
        match (self, rhs) {
365
            (
366
                &mut Self::Inner {
367
1.32k
                    size: ref mut l_size,
368
1.32k
                    keys: ref mut l_keys,
369
1.32k
                    tree: ref mut l_tree,
370
                },
371
                &mut Self::Inner {
372
1.32k
                    size: ref mut r_size,
373
1.32k
                    keys: ref mut r_keys,
374
1.32k
                    tree: ref mut r_tree,
375
                },
376
            ) => {
377
1.32k
                let l_ents = usize::from(*l_size) + 1;
378
1.32k
                let r_ents = usize::from(*r_size) + 1;
379
1.32k
                let ents = l_ents + r_ents;
380
381
1.32k
                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
1.05k
                    *l_size = 0;
385
                    // Insert `crit_key` between the two nodes.
386
1.05k
                    l_keys[l_ents - 1] = crit_key;
387
1.05k
                    l_keys[l_ents..ents - 1].copy_from_slice(&r_keys[0..r_ents - 1]);
388
1.05k
                    r_keys[0..ents - 1].copy_from_slice(&l_keys[0..ents - 1]);
389
1.05k
                    l_tree[l_ents..ents].copy_from_slice(&r_tree[0..r_ents]);
390
1.05k
                    r_tree[0..ents].copy_from_slice(&l_tree[0..ents]);
391
1.05k
                    *r_size = (ents - 1) as u8;
392
1.05k
                    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
266
                    let r_goal = ents / 2;
397
266
                    let l_goal = ents - r_goal;
398
266
                    debug_assert!(l_goal > l_ents, "Node must be underflowed");
399
400
266
                    l_keys[l_ents - 1] = crit_key;
401
266
                    l_keys[l_ents..l_goal - 1].copy_from_slice(&r_keys[0..l_goal - 1 - l_ents]);
402
266
                    l_tree[l_ents..l_goal].copy_from_slice(&r_tree[0..l_goal - l_ents]);
403
266
                    *l_size = (l_goal - 1) as u8;
404
405
266
                    let new_crit = r_keys[r_ents - r_goal - 1];
406
266
                    slice_shift(&mut r_keys[0..r_ents - 1], r_ents - r_goal);
407
266
                    slice_shift(&mut r_tree[0..r_ents], r_ents - r_goal);
408
266
                    *r_size = (r_goal - 1) as u8;
409
410
266
                    Some(new_crit)
411
                }
412
            }
413
            (
414
                &mut Self::Leaf {
415
12.9k
                    size: ref mut l_size,
416
12.9k
                    keys: ref mut l_keys,
417
12.9k
                    vals: ref mut l_vals,
418
                },
419
                &mut Self::Leaf {
420
12.9k
                    size: ref mut r_size,
421
12.9k
                    keys: ref mut r_keys,
422
12.9k
                    vals: ref mut r_vals,
423
                },
424
            ) => {
425
12.9k
                let l_ents = usize::from(*l_size);
426
12.9k
                let l_keys = l_keys.borrow_mut();
427
12.9k
                let l_vals = l_vals.borrow_mut();
428
12.9k
                let r_ents = usize::from(*r_size);
429
12.9k
                let r_keys = r_keys.borrow_mut();
430
12.9k
                let r_vals = r_vals.borrow_mut();
431
12.9k
                let ents = l_ents + r_ents;
432
433
12.9k
                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
10.0k
                    *l_size = 0;
437
10.0k
                    l_keys[l_ents..ents].copy_from_slice(&r_keys[0..r_ents]);
438
10.0k
                    r_keys[0..ents].copy_from_slice(&l_keys[0..ents]);
439
10.0k
                    l_vals[l_ents..ents].copy_from_slice(&r_vals[0..r_ents]);
440
10.0k
                    r_vals[0..ents].copy_from_slice(&l_vals[0..ents]);
441
10.0k
                    *r_size = ents as u8;
442
10.0k
                    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
2.86k
                    let r_goal = ents / 2;
447
2.86k
                    let l_goal = ents - r_goal;
448
2.86k
                    debug_assert!(l_goal > l_ents, "Node must be underflowed");
449
450
2.86k
                    l_keys[l_ents..l_goal].copy_from_slice(&r_keys[0..l_goal - l_ents]);
451
2.86k
                    l_vals[l_ents..l_goal].copy_from_slice(&r_vals[0..l_goal - l_ents]);
452
2.86k
                    *l_size = l_goal as u8;
453
454
2.86k
                    slice_shift(&mut r_keys[0..r_ents], r_ents - r_goal);
455
2.86k
                    slice_shift(&mut r_vals[0..r_ents], r_ents - r_goal);
456
2.86k
                    *r_size = r_goal as u8;
457
458
2.86k
                    Some(r_keys[0])
459
                }
460
            }
461
0
            _ => panic!("Mismatched nodes"),
462
        }
463
14.2k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<usize, wasmtime_internal_core::slab::Id>>>::balance
Line
Count
Source
363
1.40k
    pub fn balance(&mut self, crit_key: F::Key, rhs: &mut Self) -> Option<F::Key> {
364
1.40k
        match (self, rhs) {
365
            (
366
                &mut Self::Inner {
367
4
                    size: ref mut l_size,
368
4
                    keys: ref mut l_keys,
369
4
                    tree: ref mut l_tree,
370
                },
371
                &mut Self::Inner {
372
4
                    size: ref mut r_size,
373
4
                    keys: ref mut r_keys,
374
4
                    tree: ref mut r_tree,
375
                },
376
            ) => {
377
4
                let l_ents = usize::from(*l_size) + 1;
378
4
                let r_ents = usize::from(*r_size) + 1;
379
4
                let ents = l_ents + r_ents;
380
381
4
                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
4
                    *l_size = 0;
385
                    // Insert `crit_key` between the two nodes.
386
4
                    l_keys[l_ents - 1] = crit_key;
387
4
                    l_keys[l_ents..ents - 1].copy_from_slice(&r_keys[0..r_ents - 1]);
388
4
                    r_keys[0..ents - 1].copy_from_slice(&l_keys[0..ents - 1]);
389
4
                    l_tree[l_ents..ents].copy_from_slice(&r_tree[0..r_ents]);
390
4
                    r_tree[0..ents].copy_from_slice(&l_tree[0..ents]);
391
4
                    *r_size = (ents - 1) as u8;
392
4
                    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
0
                    let r_goal = ents / 2;
397
0
                    let l_goal = ents - r_goal;
398
0
                    debug_assert!(l_goal > l_ents, "Node must be underflowed");
399
400
0
                    l_keys[l_ents - 1] = crit_key;
401
0
                    l_keys[l_ents..l_goal - 1].copy_from_slice(&r_keys[0..l_goal - 1 - l_ents]);
402
0
                    l_tree[l_ents..l_goal].copy_from_slice(&r_tree[0..l_goal - l_ents]);
403
0
                    *l_size = (l_goal - 1) as u8;
404
405
0
                    let new_crit = r_keys[r_ents - r_goal - 1];
406
0
                    slice_shift(&mut r_keys[0..r_ents - 1], r_ents - r_goal);
407
0
                    slice_shift(&mut r_tree[0..r_ents], r_ents - r_goal);
408
0
                    *r_size = (r_goal - 1) as u8;
409
410
0
                    Some(new_crit)
411
                }
412
            }
413
            (
414
                &mut Self::Leaf {
415
1.40k
                    size: ref mut l_size,
416
1.40k
                    keys: ref mut l_keys,
417
1.40k
                    vals: ref mut l_vals,
418
                },
419
                &mut Self::Leaf {
420
1.40k
                    size: ref mut r_size,
421
1.40k
                    keys: ref mut r_keys,
422
1.40k
                    vals: ref mut r_vals,
423
                },
424
            ) => {
425
1.40k
                let l_ents = usize::from(*l_size);
426
1.40k
                let l_keys = l_keys.borrow_mut();
427
1.40k
                let l_vals = l_vals.borrow_mut();
428
1.40k
                let r_ents = usize::from(*r_size);
429
1.40k
                let r_keys = r_keys.borrow_mut();
430
1.40k
                let r_vals = r_vals.borrow_mut();
431
1.40k
                let ents = l_ents + r_ents;
432
433
1.40k
                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
1.09k
                    *l_size = 0;
437
1.09k
                    l_keys[l_ents..ents].copy_from_slice(&r_keys[0..r_ents]);
438
1.09k
                    r_keys[0..ents].copy_from_slice(&l_keys[0..ents]);
439
1.09k
                    l_vals[l_ents..ents].copy_from_slice(&r_vals[0..r_ents]);
440
1.09k
                    r_vals[0..ents].copy_from_slice(&l_vals[0..ents]);
441
1.09k
                    *r_size = ents as u8;
442
1.09k
                    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
304
                    let r_goal = ents / 2;
447
304
                    let l_goal = ents - r_goal;
448
304
                    debug_assert!(l_goal > l_ents, "Node must be underflowed");
449
450
304
                    l_keys[l_ents..l_goal].copy_from_slice(&r_keys[0..l_goal - l_ents]);
451
304
                    l_vals[l_ents..l_goal].copy_from_slice(&r_vals[0..l_goal - l_ents]);
452
304
                    *l_size = l_goal as u8;
453
454
304
                    slice_shift(&mut r_keys[0..r_ents], r_ents - r_goal);
455
304
                    slice_shift(&mut r_vals[0..r_ents], r_ents - r_goal);
456
304
                    *r_size = r_goal as u8;
457
458
304
                    Some(r_keys[0])
459
                }
460
            }
461
0
            _ => panic!("Mismatched nodes"),
462
        }
463
1.40k
    }
<cranelift_bforest::node::NodeData<cranelift_bforest::map::MapTypes<cranelift_codegen::ir::entities::Inst, cranelift_codegen::ir::entities::Block>>>::balance
Line
Count
Source
363
12.8k
    pub fn balance(&mut self, crit_key: F::Key, rhs: &mut Self) -> Option<F::Key> {
364
12.8k
        match (self, rhs) {
365
            (
366
                &mut Self::Inner {
367
1.32k
                    size: ref mut l_size,
368
1.32k
                    keys: ref mut l_keys,
369
1.32k
                    tree: ref mut l_tree,
370
                },
371
                &mut Self::Inner {
372
1.32k
                    size: ref mut r_size,
373
1.32k
                    keys: ref mut r_keys,
374
1.32k
                    tree: ref mut r_tree,
375
                },
376
            ) => {
377
1.32k
                let l_ents = usize::from(*l_size) + 1;
378
1.32k
                let r_ents = usize::from(*r_size) + 1;
379
1.32k
                let ents = l_ents + r_ents;
380
381
1.32k
                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
1.05k
                    *l_size = 0;
385
                    // Insert `crit_key` between the two nodes.
386
1.05k
                    l_keys[l_ents - 1] = crit_key;
387
1.05k
                    l_keys[l_ents..ents - 1].copy_from_slice(&r_keys[0..r_ents - 1]);
388
1.05k
                    r_keys[0..ents - 1].copy_from_slice(&l_keys[0..ents - 1]);
389
1.05k
                    l_tree[l_ents..ents].copy_from_slice(&r_tree[0..r_ents]);
390
1.05k
                    r_tree[0..ents].copy_from_slice(&l_tree[0..ents]);
391
1.05k
                    *r_size = (ents - 1) as u8;
392
1.05k
                    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
266
                    let r_goal = ents / 2;
397
266
                    let l_goal = ents - r_goal;
398
266
                    debug_assert!(l_goal > l_ents, "Node must be underflowed");
399
400
266
                    l_keys[l_ents - 1] = crit_key;
401
266
                    l_keys[l_ents..l_goal - 1].copy_from_slice(&r_keys[0..l_goal - 1 - l_ents]);
402
266
                    l_tree[l_ents..l_goal].copy_from_slice(&r_tree[0..l_goal - l_ents]);
403
266
                    *l_size = (l_goal - 1) as u8;
404
405
266
                    let new_crit = r_keys[r_ents - r_goal - 1];
406
266
                    slice_shift(&mut r_keys[0..r_ents - 1], r_ents - r_goal);
407
266
                    slice_shift(&mut r_tree[0..r_ents], r_ents - r_goal);
408
266
                    *r_size = (r_goal - 1) as u8;
409
410
266
                    Some(new_crit)
411
                }
412
            }
413
            (
414
                &mut Self::Leaf {
415
11.5k
                    size: ref mut l_size,
416
11.5k
                    keys: ref mut l_keys,
417
11.5k
                    vals: ref mut l_vals,
418
                },
419
                &mut Self::Leaf {
420
11.5k
                    size: ref mut r_size,
421
11.5k
                    keys: ref mut r_keys,
422
11.5k
                    vals: ref mut r_vals,
423
                },
424
            ) => {
425
11.5k
                let l_ents = usize::from(*l_size);
426
11.5k
                let l_keys = l_keys.borrow_mut();
427
11.5k
                let l_vals = l_vals.borrow_mut();
428
11.5k
                let r_ents = usize::from(*r_size);
429
11.5k
                let r_keys = r_keys.borrow_mut();
430
11.5k
                let r_vals = r_vals.borrow_mut();
431
11.5k
                let ents = l_ents + r_ents;
432
433
11.5k
                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
8.94k
                    *l_size = 0;
437
8.94k
                    l_keys[l_ents..ents].copy_from_slice(&r_keys[0..r_ents]);
438
8.94k
                    r_keys[0..ents].copy_from_slice(&l_keys[0..ents]);
439
8.94k
                    l_vals[l_ents..ents].copy_from_slice(&r_vals[0..r_ents]);
440
8.94k
                    r_vals[0..ents].copy_from_slice(&l_vals[0..ents]);
441
8.94k
                    *r_size = ents as u8;
442
8.94k
                    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
2.55k
                    let r_goal = ents / 2;
447
2.55k
                    let l_goal = ents - r_goal;
448
2.55k
                    debug_assert!(l_goal > l_ents, "Node must be underflowed");
449
450
2.55k
                    l_keys[l_ents..l_goal].copy_from_slice(&r_keys[0..l_goal - l_ents]);
451
2.55k
                    l_vals[l_ents..l_goal].copy_from_slice(&r_vals[0..l_goal - l_ents]);
452
2.55k
                    *l_size = l_goal as u8;
453
454
2.55k
                    slice_shift(&mut r_keys[0..r_ents], r_ents - r_goal);
455
2.55k
                    slice_shift(&mut r_vals[0..r_ents], r_ents - r_goal);
456
2.55k
                    *r_size = r_goal as u8;
457
458
2.55k
                    Some(r_keys[0])
459
                }
460
            }
461
0
            _ => panic!("Mismatched nodes"),
462
        }
463
12.8k
    }
Unexecuted instantiation: <cranelift_bforest::node::NodeData<_>>::balance
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
1.33M
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
1.33M
    if ins <= len / 2 {
476
98.8k
        len / 2
477
    } else {
478
1.23M
        (len + 1) / 2
479
    }
480
1.33M
}
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
164k
    fn new(removed: usize, new_size: usize, capacity: usize) -> Self {
522
164k
        if 2 * new_size >= capacity {
523
38.9k
            if removed == new_size {
524
888
                Self::Rightmost
525
            } else {
526
38.0k
                Self::Healthy
527
            }
528
126k
        } else if new_size > 0 {
529
69.6k
            Self::Underflow
530
        } else {
531
56.4k
            Self::Empty
532
        }
533
164k
    }
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
}