Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/entity/src/set.rs
3069 views
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
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32
f.debug_set().entries(self.keys()).finish()
33
}
34
}
35
36
impl<K: EntityRef> Default for EntitySet<K> {
37
fn default() -> Self {
38
Self {
39
bitset: CompoundBitSet::default(),
40
unused: PhantomData,
41
}
42
}
43
}
44
45
impl<K: EntityRef> Extend<K> for EntitySet<K> {
46
fn extend<T: IntoIterator<Item = K>>(&mut self, iter: T) {
47
for k in iter {
48
self.insert(k);
49
}
50
}
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
pub fn new() -> Self {
60
Self::default()
61
}
62
63
/// Creates a new empty set with the specified capacity.
64
pub fn with_capacity(capacity: usize) -> Self {
65
Self {
66
bitset: CompoundBitSet::with_capacity(capacity),
67
unused: PhantomData,
68
}
69
}
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
pub fn contains(&self, k: K) -> bool {
92
let index = k.index();
93
self.bitset.contains(index)
94
}
95
96
/// Is this set completely empty?
97
pub fn is_empty(&self) -> bool {
98
self.bitset.is_empty()
99
}
100
101
/// Remove all entries from this set.
102
pub fn clear(&mut self) {
103
self.bitset.clear()
104
}
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
pub fn keys(&self) -> Keys<K> {
128
Keys::with_len(self.bitset.max().map_or(0, |x| x + 1))
129
}
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
pub fn iter(&self) -> SetIter<'_, K> {
150
SetIter {
151
inner: self.bitset.iter(),
152
_phantom: PhantomData,
153
}
154
}
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
pub fn insert(&mut self, k: K) -> bool {
161
let index = k.index();
162
self.bitset.insert(index)
163
}
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
fn next(&mut self) -> Option<Self::Item> {
194
let k = self.inner.next()?;
195
Some(K::new(k))
196
}
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
}
311
312