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