Coverage Report

Created: 2026-03-26 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/cranelift-entity-0.129.1/src/set.rs
Line
Count
Source
1
//! Densely numbered entity references as set keys.
2
3
use crate::EntityRef;
4
use crate::keys::Keys;
5
use core::fmt;
6
use core::marker::PhantomData;
7
use cranelift_bitset::CompoundBitSet;
8
use wasmtime_core::error::OutOfMemory;
9
10
/// A set of `K` for densely indexed entity references.
11
///
12
/// The `EntitySet` data structure uses the dense index space to implement a set with a bitvector.
13
/// Like `SecondaryMap`, an `EntitySet` is used to associate secondary information with entities.
14
#[derive(Clone, PartialEq, Eq)]
15
#[cfg_attr(
16
    feature = "enable-serde",
17
    derive(serde_derive::Serialize, serde_derive::Deserialize)
18
)]
19
pub struct EntitySet<K>
20
where
21
    K: EntityRef,
22
{
23
    bitset: CompoundBitSet,
24
    unused: PhantomData<K>,
25
}
26
27
impl<K> fmt::Debug for EntitySet<K>
28
where
29
    K: fmt::Debug + EntityRef,
30
{
31
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32
0
        f.debug_set().entries(self.keys()).finish()
33
0
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value> as core::fmt::Debug>::fmt
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value> as core::fmt::Debug>::fmt
34
}
35
36
impl<K: EntityRef> Default for EntitySet<K> {
37
1.12M
    fn default() -> Self {
38
1.12M
        Self {
39
1.12M
            bitset: CompoundBitSet::default(),
40
1.12M
            unused: PhantomData,
41
1.12M
        }
42
1.12M
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable> as core::default::Default>::default
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block> as core::default::Default>::default
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value> as core::default::Default>::default
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block> as core::default::Default>::default
<cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable> as core::default::Default>::default
Line
Count
Source
37
146k
    fn default() -> Self {
38
146k
        Self {
39
146k
            bitset: CompoundBitSet::default(),
40
146k
            unused: PhantomData,
41
146k
        }
42
146k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block> as core::default::Default>::default
Line
Count
Source
37
292k
    fn default() -> Self {
38
292k
        Self {
39
292k
            bitset: CompoundBitSet::default(),
40
292k
            unused: PhantomData,
41
292k
        }
42
292k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value> as core::default::Default>::default
Line
Count
Source
37
292k
    fn default() -> Self {
38
292k
        Self {
39
292k
            bitset: CompoundBitSet::default(),
40
292k
            unused: PhantomData,
41
292k
        }
42
292k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block> as core::default::Default>::default
Line
Count
Source
37
396k
    fn default() -> Self {
38
396k
        Self {
39
396k
            bitset: CompoundBitSet::default(),
40
396k
            unused: PhantomData,
41
396k
        }
42
396k
    }
43
}
44
45
impl<K: EntityRef> Extend<K> for EntitySet<K> {
46
0
    fn extend<T: IntoIterator<Item = K>>(&mut self, iter: T) {
47
0
        for k in iter {
48
0
            self.insert(k);
49
0
        }
50
0
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value> as core::iter::traits::collect::Extend<cranelift_codegen::ir::entities::Value>>::extend::<core::iter::adapters::copied::Copied<core::slice::iter::Iter<cranelift_codegen::ir::entities::Value>>>
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value> as core::iter::traits::collect::Extend<cranelift_codegen::ir::entities::Value>>::extend::<core::iter::adapters::copied::Copied<core::slice::iter::Iter<cranelift_codegen::ir::entities::Value>>>
51
}
52
53
/// Shared `EntitySet` implementation for all value types.
54
impl<K> EntitySet<K>
55
where
56
    K: EntityRef,
57
{
58
    /// Create a new empty set.
59
307
    pub fn new() -> Self {
60
307
        Self::default()
61
307
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::new
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::new
Line
Count
Source
59
307
    pub fn new() -> Self {
60
307
        Self::default()
61
307
    }
62
63
    /// Creates a new empty set with the specified capacity.
64
595k
    pub fn with_capacity(capacity: usize) -> Self {
65
595k
        Self {
66
595k
            bitset: CompoundBitSet::with_capacity(capacity),
67
595k
            unused: PhantomData,
68
595k
        }
69
595k
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::ExceptionTable>>::with_capacity
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::with_capacity
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::JumpTable>>::with_capacity
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::ExceptionTable>>::with_capacity
Line
Count
Source
64
198k
    pub fn with_capacity(capacity: usize) -> Self {
65
198k
        Self {
66
198k
            bitset: CompoundBitSet::with_capacity(capacity),
67
198k
            unused: PhantomData,
68
198k
        }
69
198k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::with_capacity
Line
Count
Source
64
198k
    pub fn with_capacity(capacity: usize) -> Self {
65
198k
        Self {
66
198k
            bitset: CompoundBitSet::with_capacity(capacity),
67
198k
            unused: PhantomData,
68
198k
        }
69
198k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::JumpTable>>::with_capacity
Line
Count
Source
64
198k
    pub fn with_capacity(capacity: usize) -> Self {
65
198k
        Self {
66
198k
            bitset: CompoundBitSet::with_capacity(capacity),
67
198k
            unused: PhantomData,
68
198k
        }
69
198k
    }
70
71
    /// Like `with_capacity` but returns an error on allocation failure.
72
    pub fn try_with_capacity(capacity: usize) -> Result<Self, OutOfMemory> {
73
        Ok(Self {
74
            bitset: CompoundBitSet::try_with_capacity(capacity)?,
75
            unused: PhantomData,
76
        })
77
    }
78
79
    /// Ensure that the set has enough capacity to hold `capacity` total
80
    /// elements.
81
    pub fn ensure_capacity(&mut self, capacity: usize) {
82
        self.bitset.ensure_capacity(capacity);
83
    }
84
85
    /// Like `ensure_capacity` but returns an error on allocation failure.
86
    pub fn try_ensure_capacity(&mut self, capacity: usize) -> Result<(), OutOfMemory> {
87
        self.bitset.try_ensure_capacity(capacity)
88
    }
89
90
    /// Get the element at `k` if it exists.
91
28.5M
    pub fn contains(&self, k: K) -> bool {
92
28.5M
        let index = k.index();
93
28.5M
        self.bitset.contains(index)
94
28.5M
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::contains
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::ExceptionTable>>::contains
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::contains
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::contains
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::JumpTable>>::contains
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::contains
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::ExceptionTable>>::contains
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::contains
Line
Count
Source
91
1.92M
    pub fn contains(&self, k: K) -> bool {
92
1.92M
        let index = k.index();
93
1.92M
        self.bitset.contains(index)
94
1.92M
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::contains
Line
Count
Source
91
26.5M
    pub fn contains(&self, k: K) -> bool {
92
26.5M
        let index = k.index();
93
26.5M
        self.bitset.contains(index)
94
26.5M
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::JumpTable>>::contains
Line
Count
Source
91
307
    pub fn contains(&self, k: K) -> bool {
92
307
        let index = k.index();
93
307
        self.bitset.contains(index)
94
307
    }
95
96
    /// Is this set completely empty?
97
198k
    pub fn is_empty(&self) -> bool {
98
198k
        self.bitset.is_empty()
99
198k
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::is_empty
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::is_empty
Line
Count
Source
97
198k
    pub fn is_empty(&self) -> bool {
98
198k
        self.bitset.is_empty()
99
198k
    }
100
101
    /// Remove all entries from this set.
102
1.32M
    pub fn clear(&mut self) {
103
1.32M
        self.bitset.clear()
104
1.32M
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable>>::clear
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::clear
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::clear
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::clear
<cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable>>::clear
Line
Count
Source
102
198k
    pub fn clear(&mut self) {
103
198k
        self.bitset.clear()
104
198k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::clear
Line
Count
Source
102
330k
    pub fn clear(&mut self) {
103
330k
        self.bitset.clear()
104
330k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::clear
Line
Count
Source
102
396k
    pub fn clear(&mut self) {
103
396k
        self.bitset.clear()
104
396k
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::clear
Line
Count
Source
102
396k
    pub fn clear(&mut self) {
103
396k
        self.bitset.clear()
104
396k
    }
105
106
    /// Iterate over all the keys up to the maximum in this set.
107
    ///
108
    /// This will yield intermediate keys on the way up to the max key, even if
109
    /// they are not contained within the set.
110
    ///
111
    /// ```
112
    /// use cranelift_entity::{entity_impl, EntityRef, EntitySet};
113
    ///
114
    /// #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
115
    /// struct Entity(u32);
116
    /// entity_impl!(Entity);
117
    ///
118
    /// let mut set = EntitySet::new();
119
    /// set.insert(Entity::new(2));
120
    ///
121
    /// let mut keys = set.keys();
122
    /// assert_eq!(keys.next(), Some(Entity::new(0)));
123
    /// assert_eq!(keys.next(), Some(Entity::new(1)));
124
    /// assert_eq!(keys.next(), Some(Entity::new(2)));
125
    /// assert!(keys.next().is_none());
126
    /// ```
127
0
    pub fn keys(&self) -> Keys<K> {
128
0
        Keys::with_len(self.bitset.max().map_or(0, |x| x + 1))
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::keys::{closure#0}
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::keys::{closure#0}
129
0
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::keys
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::keys
130
131
    /// Iterate over the elements of this set.
132
    ///
133
    /// ```
134
    /// use cranelift_entity::{entity_impl, EntityRef, EntitySet};
135
    ///
136
    /// #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
137
    /// struct Entity(u32);
138
    /// entity_impl!(Entity);
139
    ///
140
    /// let mut set = EntitySet::new();
141
    /// set.insert(Entity::new(2));
142
    /// set.insert(Entity::new(3));
143
    ///
144
    /// let mut iter = set.iter();
145
    /// assert_eq!(iter.next(), Some(Entity::new(2)));
146
    /// assert_eq!(iter.next(), Some(Entity::new(3)));
147
    /// assert!(iter.next().is_none());
148
    /// ```
149
198k
    pub fn iter(&self) -> SetIter<'_, K> {
150
198k
        SetIter {
151
198k
            inner: self.bitset.iter(),
152
198k
            _phantom: PhantomData,
153
198k
        }
154
198k
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable>>::iter
<cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable>>::iter
Line
Count
Source
149
198k
    pub fn iter(&self) -> SetIter<'_, K> {
150
198k
        SetIter {
151
198k
            inner: self.bitset.iter(),
152
198k
            _phantom: PhantomData,
153
198k
        }
154
198k
    }
155
156
    /// Insert the element at `k`.
157
    ///
158
    /// Returns `true` if `k` was not present in the set, i.e. this is a
159
    /// newly-added element. Returns `false` otherwise.
160
15.5M
    pub fn insert(&mut self, k: K) -> bool {
161
15.5M
        let index = k.index();
162
15.5M
        self.bitset.insert(index)
163
15.5M
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::ExceptionTable>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::JumpTable>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_frontend::variable::Variable>>::insert
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::insert
Line
Count
Source
160
335k
    pub fn insert(&mut self, k: K) -> bool {
161
335k
        let index = k.index();
162
335k
        self.bitset.insert(index)
163
335k
    }
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::insert
Unexecuted instantiation: <cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::ExceptionTable>>::insert
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Block>>::insert
Line
Count
Source
160
1.35M
    pub fn insert(&mut self, k: K) -> bool {
161
1.35M
        let index = k.index();
162
1.35M
        self.bitset.insert(index)
163
1.35M
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::Value>>::insert
Line
Count
Source
160
13.8M
    pub fn insert(&mut self, k: K) -> bool {
161
13.8M
        let index = k.index();
162
13.8M
        self.bitset.insert(index)
163
13.8M
    }
<cranelift_entity::set::EntitySet<cranelift_codegen::ir::entities::JumpTable>>::insert
Line
Count
Source
160
307
    pub fn insert(&mut self, k: K) -> bool {
161
307
        let index = k.index();
162
307
        self.bitset.insert(index)
163
307
    }
164
165
    /// Remove `k` from this bitset.
166
    ///
167
    /// Returns whether `k` was previously in this set or not.
168
    pub fn remove(&mut self, k: K) -> bool {
169
        let index = k.index();
170
        self.bitset.remove(index)
171
    }
172
173
    /// Removes and returns the highest-index entity from the set if it exists.
174
    pub fn pop(&mut self) -> Option<K> {
175
        let index = self.bitset.pop()?;
176
        Some(K::new(index))
177
    }
178
}
179
180
/// An iterator over the elements in an `EntitySet`.
181
pub struct SetIter<'a, K> {
182
    inner: cranelift_bitset::compound::Iter<'a>,
183
    _phantom: PhantomData<K>,
184
}
185
186
impl<K> Iterator for SetIter<'_, K>
187
where
188
    K: EntityRef,
189
{
190
    type Item = K;
191
192
    #[inline]
193
198k
    fn next(&mut self) -> Option<Self::Item> {
194
198k
        let k = self.inner.next()?;
195
0
        Some(K::new(k))
196
198k
    }
Unexecuted instantiation: <cranelift_entity::set::SetIter<cranelift_frontend::variable::Variable> as core::iter::traits::iterator::Iterator>::next
<cranelift_entity::set::SetIter<cranelift_frontend::variable::Variable> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
193
198k
    fn next(&mut self) -> Option<Self::Item> {
194
198k
        let k = self.inner.next()?;
195
0
        Some(K::new(k))
196
198k
    }
197
}
198
199
#[cfg(test)]
200
mod tests {
201
    use super::*;
202
    use alloc::vec::Vec;
203
    use core::u32;
204
205
    // `EntityRef` impl for testing.
206
    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
207
    struct E(u32);
208
209
    impl EntityRef for E {
210
        fn new(i: usize) -> Self {
211
            E(i as u32)
212
        }
213
        fn index(self) -> usize {
214
            self.0 as usize
215
        }
216
    }
217
218
    #[test]
219
    fn basic() {
220
        let r0 = E(0);
221
        let r1 = E(1);
222
        let r2 = E(2);
223
        let mut m = EntitySet::new();
224
225
        let v: Vec<E> = m.keys().collect();
226
        assert_eq!(v, []);
227
        assert!(m.is_empty());
228
229
        m.insert(r2);
230
        m.insert(r1);
231
232
        assert!(!m.contains(r0));
233
        assert!(m.contains(r1));
234
        assert!(m.contains(r2));
235
        assert!(!m.contains(E(3)));
236
        assert!(!m.is_empty());
237
238
        let v: Vec<E> = m.keys().collect();
239
        assert_eq!(v, [r0, r1, r2]);
240
241
        assert!(!m.contains(E(3)));
242
        assert!(!m.contains(E(4)));
243
        assert!(!m.contains(E(8)));
244
        assert!(!m.contains(E(15)));
245
        assert!(!m.contains(E(19)));
246
247
        m.insert(E(8));
248
        m.insert(E(15));
249
        assert!(!m.contains(E(3)));
250
        assert!(!m.contains(E(4)));
251
        assert!(m.contains(E(8)));
252
        assert!(!m.contains(E(9)));
253
        assert!(!m.contains(E(14)));
254
        assert!(m.contains(E(15)));
255
        assert!(!m.contains(E(16)));
256
        assert!(!m.contains(E(19)));
257
        assert!(!m.contains(E(20)));
258
        assert!(!m.contains(E(u32::MAX)));
259
260
        m.clear();
261
        assert!(m.is_empty());
262
    }
263
264
    #[test]
265
    fn pop_ordered() {
266
        let r0 = E(0);
267
        let r1 = E(1);
268
        let r2 = E(2);
269
        let mut m = EntitySet::new();
270
        m.insert(r0);
271
        m.insert(r1);
272
        m.insert(r2);
273
274
        assert_eq!(r2, m.pop().unwrap());
275
        assert_eq!(r1, m.pop().unwrap());
276
        assert_eq!(r0, m.pop().unwrap());
277
        assert!(m.pop().is_none());
278
        assert!(m.pop().is_none());
279
    }
280
281
    #[test]
282
    fn pop_unordered() {
283
        let mut blocks = [
284
            E(0),
285
            E(1),
286
            E(6),
287
            E(7),
288
            E(5),
289
            E(9),
290
            E(10),
291
            E(2),
292
            E(3),
293
            E(11),
294
            E(12),
295
        ];
296
297
        let mut m = EntitySet::new();
298
        for &block in &blocks {
299
            m.insert(block);
300
        }
301
        assert_eq!(m.bitset.max(), Some(12));
302
        blocks.sort();
303
304
        for &block in blocks.iter().rev() {
305
            assert_eq!(block, m.pop().unwrap());
306
        }
307
308
        assert!(m.is_empty());
309
    }
310
}