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