1 //! Sparse mapping of entity references to larger value types. 2 //! 3 //! This module provides a `SparseMap` data structure which implements a sparse mapping from an 4 //! `EntityRef` key to a value type that may be on the larger side. This implementation is based on 5 //! the paper: 6 //! 7 //! > Briggs, Torczon, *An efficient representation for sparse sets*, 8 //! > ACM Letters on Programming Languages and Systems, Volume 2, Issue 1-4, March-Dec. 1993. 9 10 use crate::EntityRef; 11 use crate::map::SecondaryMap; 12 use alloc::vec::Vec; 13 use core::fmt; 14 use core::mem; 15 use core::slice; 16 use core::u32; 17 18 #[cfg(feature = "enable-serde")] 19 use serde_derive::{Deserialize, Serialize}; 20 21 /// Trait for extracting keys from values stored in a `SparseMap`. 22 /// 23 /// All values stored in a `SparseMap` must keep track of their own key in the map and implement 24 /// this trait to provide access to the key. 25 pub trait SparseMapValue<K> { 26 /// Get the key of this sparse map value. This key is not allowed to change while the value 27 /// is a member of the map. key(&self) -> K28 fn key(&self) -> K; 29 } 30 31 /// A sparse mapping of entity references. 32 /// 33 /// A `SparseMap<K, V>` map provides: 34 /// 35 /// - Memory usage equivalent to `SecondaryMap<K, u32>` + `Vec<V>`, so much smaller than 36 /// `SecondaryMap<K, V>` for sparse mappings of larger `V` types. 37 /// - Constant time lookup, slightly slower than `SecondaryMap`. 38 /// - A very fast, constant time `clear()` operation. 39 /// - Fast insert and erase operations. 40 /// - Stable iteration that is as fast as a `Vec<V>`. 41 /// 42 /// # Compared to `SecondaryMap` 43 /// 44 /// When should we use a `SparseMap` instead of a secondary `SecondaryMap`? First of all, 45 /// `SparseMap` does not provide the functionality of a `PrimaryMap` which can allocate and assign 46 /// entity references to objects as they are pushed onto the map. It is only the secondary entity 47 /// maps that can be replaced with a `SparseMap`. 48 /// 49 /// - A secondary entity map assigns a default mapping to all keys. It doesn't distinguish between 50 /// an unmapped key and one that maps to the default value. `SparseMap` does not require 51 /// `Default` values, and it tracks accurately if a key has been mapped or not. 52 /// - Iterating over the contents of an `SecondaryMap` is linear in the size of the *key space*, 53 /// while iterating over a `SparseMap` is linear in the number of elements in the mapping. This 54 /// is an advantage precisely when the mapping is sparse. 55 /// - `SparseMap::clear()` is constant time and super-fast. `SecondaryMap::clear()` is linear in 56 /// the size of the key space. (Or, rather the required `resize()` call following the `clear()` 57 /// is). 58 /// - `SparseMap` requires the values to implement `SparseMapValue<K>` which means that they must 59 /// contain their own key. 60 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] 61 pub struct SparseMap<K, V> 62 where 63 K: EntityRef, 64 V: SparseMapValue<K>, 65 { 66 sparse: SecondaryMap<K, u32>, 67 dense: Vec<V>, 68 } 69 70 impl<K, V> SparseMap<K, V> 71 where 72 K: EntityRef, 73 V: SparseMapValue<K>, 74 { 75 /// Create a new empty mapping. new() -> Self76 pub fn new() -> Self { 77 Self { 78 sparse: SecondaryMap::new(), 79 dense: Vec::new(), 80 } 81 } 82 83 /// Returns the number of elements in the map. len(&self) -> usize84 pub fn len(&self) -> usize { 85 self.dense.len() 86 } 87 88 /// Returns true is the map contains no elements. is_empty(&self) -> bool89 pub fn is_empty(&self) -> bool { 90 self.dense.is_empty() 91 } 92 93 /// Remove all elements from the mapping. clear(&mut self)94 pub fn clear(&mut self) { 95 self.dense.clear(); 96 } 97 98 /// Returns a reference to the value corresponding to the key. get(&self, key: K) -> Option<&V>99 pub fn get(&self, key: K) -> Option<&V> { 100 if let Some(idx) = self.sparse.get(key).cloned() { 101 if let Some(entry) = self.dense.get(idx as usize) { 102 if entry.key() == key { 103 return Some(entry); 104 } 105 } 106 } 107 None 108 } 109 110 /// Returns a mutable reference to the value corresponding to the key. 111 /// 112 /// Note that the returned value must not be mutated in a way that would change its key. This 113 /// would invalidate the sparse set data structure. get_mut(&mut self, key: K) -> Option<&mut V>114 pub fn get_mut(&mut self, key: K) -> Option<&mut V> { 115 if let Some(idx) = self.sparse.get(key).cloned() { 116 if let Some(entry) = self.dense.get_mut(idx as usize) { 117 if entry.key() == key { 118 return Some(entry); 119 } 120 } 121 } 122 None 123 } 124 125 /// Return the index into `dense` of the value corresponding to `key`. index(&self, key: K) -> Option<usize>126 fn index(&self, key: K) -> Option<usize> { 127 if let Some(idx) = self.sparse.get(key).cloned() { 128 let idx = idx as usize; 129 if let Some(entry) = self.dense.get(idx) { 130 if entry.key() == key { 131 return Some(idx); 132 } 133 } 134 } 135 None 136 } 137 138 /// Return `true` if the map contains a value corresponding to `key`. contains_key(&self, key: K) -> bool139 pub fn contains_key(&self, key: K) -> bool { 140 self.get(key).is_some() 141 } 142 143 /// Insert a value into the map. 144 /// 145 /// If the map did not have this key present, `None` is returned. 146 /// 147 /// If the map did have this key present, the value is updated, and the old value is returned. 148 /// 149 /// It is not necessary to provide a key since the value knows its own key already. insert(&mut self, value: V) -> Option<V>150 pub fn insert(&mut self, value: V) -> Option<V> { 151 let key = value.key(); 152 153 // Replace the existing entry for `key` if there is one. 154 if let Some(entry) = self.get_mut(key) { 155 return Some(mem::replace(entry, value)); 156 } 157 158 // There was no previous entry for `key`. Add it to the end of `dense`. 159 let idx = self.dense.len(); 160 debug_assert!(idx <= u32::MAX as usize, "SparseMap overflow"); 161 self.dense.push(value); 162 self.sparse[key] = idx as u32; 163 None 164 } 165 166 /// Remove a value from the map and return it. remove(&mut self, key: K) -> Option<V>167 pub fn remove(&mut self, key: K) -> Option<V> { 168 if let Some(idx) = self.index(key) { 169 let back = self.dense.pop().unwrap(); 170 171 // Are we popping the back of `dense`? 172 if idx == self.dense.len() { 173 return Some(back); 174 } 175 176 // We're removing an element from the middle of `dense`. 177 // Replace the element at `idx` with the back of `dense`. 178 // Repair `sparse` first. 179 self.sparse[back.key()] = idx as u32; 180 return Some(mem::replace(&mut self.dense[idx], back)); 181 } 182 183 // Nothing to remove. 184 None 185 } 186 187 /// Remove the last value from the map. pop(&mut self) -> Option<V>188 pub fn pop(&mut self) -> Option<V> { 189 self.dense.pop() 190 } 191 192 /// Get an iterator over the values in the map. 193 /// 194 /// The iteration order is entirely determined by the preceding sequence of `insert` and 195 /// `remove` operations. In particular, if no elements were removed, this is the insertion 196 /// order. values(&self) -> slice::Iter<'_, V>197 pub fn values(&self) -> slice::Iter<'_, V> { 198 self.dense.iter() 199 } 200 201 /// Get the values as a slice. as_slice(&self) -> &[V]202 pub fn as_slice(&self) -> &[V] { 203 self.dense.as_slice() 204 } 205 } 206 207 impl<K, V> Default for SparseMap<K, V> 208 where 209 K: EntityRef, 210 V: SparseMapValue<K>, 211 { default() -> SparseMap<K, V>212 fn default() -> SparseMap<K, V> { 213 SparseMap::new() 214 } 215 } 216 217 impl<K, V> fmt::Debug for SparseMap<K, V> 218 where 219 K: EntityRef + fmt::Debug, 220 V: SparseMapValue<K> + fmt::Debug, 221 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 223 f.debug_map() 224 .entries(self.values().map(|v| (v.key(), v))) 225 .finish() 226 } 227 } 228 229 /// Iterating over the elements of a set. 230 impl<'a, K, V> IntoIterator for &'a SparseMap<K, V> 231 where 232 K: EntityRef, 233 V: SparseMapValue<K>, 234 { 235 type Item = &'a V; 236 type IntoIter = slice::Iter<'a, V>; 237 into_iter(self) -> Self::IntoIter238 fn into_iter(self) -> Self::IntoIter { 239 self.values() 240 } 241 } 242 243 /// Any `EntityRef` can be used as a sparse map value representing itself. 244 impl<T> SparseMapValue<T> for T 245 where 246 T: EntityRef, 247 { key(&self) -> Self248 fn key(&self) -> Self { 249 *self 250 } 251 } 252 253 /// A sparse set of entity references. 254 /// 255 /// Any type that implements `EntityRef` can be used as a sparse set value too. 256 pub type SparseSet<T> = SparseMap<T, T>; 257 258 #[cfg(test)] 259 mod tests { 260 use alloc::format; 261 262 use super::*; 263 264 /// An opaque reference to an instruction in a function. 265 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 266 pub struct Inst(u32); 267 entity_impl!(Inst, "inst"); 268 269 // Mock key-value object for testing. 270 #[derive(PartialEq, Eq, Debug)] 271 struct Obj(Inst, &'static str); 272 273 impl SparseMapValue<Inst> for Obj { key(&self) -> Inst274 fn key(&self) -> Inst { 275 self.0 276 } 277 } 278 279 #[test] empty_immutable_map()280 fn empty_immutable_map() { 281 let i1 = Inst::new(1); 282 let map: SparseMap<Inst, Obj> = SparseMap::new(); 283 284 assert!(map.is_empty()); 285 assert_eq!(map.len(), 0); 286 assert_eq!(map.get(i1), None); 287 assert_eq!(map.values().count(), 0); 288 } 289 290 #[test] single_entry()291 fn single_entry() { 292 let i0 = Inst::new(0); 293 let i1 = Inst::new(1); 294 let i2 = Inst::new(2); 295 let mut map = SparseMap::new(); 296 297 assert!(map.is_empty()); 298 assert_eq!(map.len(), 0); 299 assert_eq!(map.get(i1), None); 300 assert_eq!(map.get_mut(i1), None); 301 assert_eq!(map.remove(i1), None); 302 303 assert_eq!(map.insert(Obj(i1, "hi")), None); 304 assert!(!map.is_empty()); 305 assert_eq!(map.len(), 1); 306 assert_eq!(map.get(i0), None); 307 assert_eq!(map.get(i1), Some(&Obj(i1, "hi"))); 308 assert_eq!(map.get(i2), None); 309 assert_eq!(map.get_mut(i0), None); 310 assert_eq!(map.get_mut(i1), Some(&mut Obj(i1, "hi"))); 311 assert_eq!(map.get_mut(i2), None); 312 313 assert_eq!(map.remove(i0), None); 314 assert_eq!(map.remove(i2), None); 315 assert_eq!(map.remove(i1), Some(Obj(i1, "hi"))); 316 assert_eq!(map.len(), 0); 317 assert_eq!(map.get(i1), None); 318 assert_eq!(map.get_mut(i1), None); 319 assert_eq!(map.remove(i0), None); 320 assert_eq!(map.remove(i1), None); 321 assert_eq!(map.remove(i2), None); 322 } 323 324 #[test] multiple_entries()325 fn multiple_entries() { 326 let i0 = Inst::new(0); 327 let i1 = Inst::new(1); 328 let i2 = Inst::new(2); 329 let i3 = Inst::new(3); 330 let mut map = SparseMap::new(); 331 332 assert_eq!(map.insert(Obj(i2, "foo")), None); 333 assert_eq!(map.insert(Obj(i1, "bar")), None); 334 assert_eq!(map.insert(Obj(i0, "baz")), None); 335 336 // Iteration order = insertion order when nothing has been removed yet. 337 assert_eq!( 338 map.values().map(|obj| obj.1).collect::<Vec<_>>(), 339 ["foo", "bar", "baz"] 340 ); 341 342 assert_eq!(map.len(), 3); 343 assert_eq!(map.get(i0), Some(&Obj(i0, "baz"))); 344 assert_eq!(map.get(i1), Some(&Obj(i1, "bar"))); 345 assert_eq!(map.get(i2), Some(&Obj(i2, "foo"))); 346 assert_eq!(map.get(i3), None); 347 348 // Remove front object, causing back to be swapped down. 349 assert_eq!(map.remove(i1), Some(Obj(i1, "bar"))); 350 assert_eq!(map.len(), 2); 351 assert_eq!(map.get(i0), Some(&Obj(i0, "baz"))); 352 assert_eq!(map.get(i1), None); 353 assert_eq!(map.get(i2), Some(&Obj(i2, "foo"))); 354 assert_eq!(map.get(i3), None); 355 356 // Reinsert something at a previously used key. 357 assert_eq!(map.insert(Obj(i1, "barbar")), None); 358 assert_eq!(map.len(), 3); 359 assert_eq!(map.get(i0), Some(&Obj(i0, "baz"))); 360 assert_eq!(map.get(i1), Some(&Obj(i1, "barbar"))); 361 assert_eq!(map.get(i2), Some(&Obj(i2, "foo"))); 362 assert_eq!(map.get(i3), None); 363 364 // Replace an entry. 365 assert_eq!(map.insert(Obj(i0, "bazbaz")), Some(Obj(i0, "baz"))); 366 assert_eq!(map.len(), 3); 367 assert_eq!(map.get(i0), Some(&Obj(i0, "bazbaz"))); 368 assert_eq!(map.get(i1), Some(&Obj(i1, "barbar"))); 369 assert_eq!(map.get(i2), Some(&Obj(i2, "foo"))); 370 assert_eq!(map.get(i3), None); 371 372 // Check the reference `IntoIter` impl. 373 let mut v = Vec::new(); 374 for i in &map { 375 v.push(i.1); 376 } 377 assert_eq!(v.len(), map.len()); 378 } 379 380 #[test] entity_set()381 fn entity_set() { 382 let i0 = Inst::new(0); 383 let i1 = Inst::new(1); 384 let mut set = SparseSet::new(); 385 386 assert_eq!(set.insert(i0), None); 387 assert_eq!(set.insert(i0), Some(i0)); 388 assert_eq!(set.insert(i1), None); 389 assert_eq!(set.get(i0), Some(&i0)); 390 assert_eq!(set.get(i1), Some(&i1)); 391 } 392 393 #[test] default_impl()394 fn default_impl() { 395 let map: SparseMap<Inst, Obj> = SparseMap::default(); 396 397 assert!(map.is_empty()); 398 assert_eq!(map.len(), 0); 399 } 400 401 #[test] debug_impl()402 fn debug_impl() { 403 let i1 = Inst::new(1); 404 let mut map = SparseMap::new(); 405 assert_eq!(map.insert(Obj(i1, "hi")), None); 406 407 let debug = format!("{map:?}"); 408 let expected = "{inst1: Obj(inst1, \"hi\")}"; 409 assert_eq!(debug, expected); 410 } 411 } 412