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 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result31 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> { default() -> Self37 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> { extend<T: IntoIterator<Item = K>>(&mut self, iter: T)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. new() -> Self59 pub fn new() -> Self { 60 Self::default() 61 } 62 63 /// Creates a new empty set with the specified capacity. with_capacity(capacity: usize) -> Self64 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. try_with_capacity(capacity: usize) -> Result<Self, OutOfMemory>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. ensure_capacity(&mut self, capacity: usize)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. try_ensure_capacity(&mut self, capacity: usize) -> Result<(), OutOfMemory>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. contains(&self, k: K) -> bool91 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? is_empty(&self) -> bool97 pub fn is_empty(&self) -> bool { 98 self.bitset.is_empty() 99 } 100 101 /// Remove all entries from this set. clear(&mut self)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 /// ``` keys(&self) -> Keys<K>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 /// ``` iter(&self) -> SetIter<'_, K>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. insert(&mut self, k: K) -> bool160 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. remove(&mut self, k: K) -> bool168 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. pop(&mut self) -> Option<K>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] next(&mut self) -> Option<Self::Item>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 { new(i: usize) -> Self210 fn new(i: usize) -> Self { 211 E(i as u32) 212 } index(self) -> usize213 fn index(self) -> usize { 214 self.0 as usize 215 } 216 } 217 218 #[test] basic()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] pop_ordered()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] pop_unordered()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