cranelift_entity/
sparse.rs

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
10use crate::map::SecondaryMap;
11use crate::EntityRef;
12use alloc::vec::Vec;
13use core::fmt;
14use core::mem;
15use core::slice;
16use core::u32;
17
18#[cfg(feature = "enable-serde")]
19use 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.
25pub 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.
28    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))]
61pub struct SparseMap<K, V>
62where
63    K: EntityRef,
64    V: SparseMapValue<K>,
65{
66    sparse: SecondaryMap<K, u32>,
67    dense: Vec<V>,
68}
69
70impl<K, V> SparseMap<K, V>
71where
72    K: EntityRef,
73    V: SparseMapValue<K>,
74{
75    /// Create a new empty mapping.
76    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.
84    pub fn len(&self) -> usize {
85        self.dense.len()
86    }
87
88    /// Returns true is the map contains no elements.
89    pub fn is_empty(&self) -> bool {
90        self.dense.is_empty()
91    }
92
93    /// Remove all elements from the mapping.
94    pub fn clear(&mut self) {
95        self.dense.clear();
96    }
97
98    /// Returns a reference to the value corresponding to the key.
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.
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`.
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`.
139    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.
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.
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.
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.
197    pub fn values(&self) -> slice::Iter<V> {
198        self.dense.iter()
199    }
200
201    /// Get the values as a slice.
202    pub fn as_slice(&self) -> &[V] {
203        self.dense.as_slice()
204    }
205}
206
207impl<K, V> Default for SparseMap<K, V>
208where
209    K: EntityRef,
210    V: SparseMapValue<K>,
211{
212    fn default() -> SparseMap<K, V> {
213        SparseMap::new()
214    }
215}
216
217impl<K, V> fmt::Debug for SparseMap<K, V>
218where
219    K: EntityRef + fmt::Debug,
220    V: SparseMapValue<K> + fmt::Debug,
221{
222    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.
230impl<'a, K, V> IntoIterator for &'a SparseMap<K, V>
231where
232    K: EntityRef,
233    V: SparseMapValue<K>,
234{
235    type Item = &'a V;
236    type IntoIter = slice::Iter<'a, V>;
237
238    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.
244impl<T> SparseMapValue<T> for T
245where
246    T: EntityRef,
247{
248    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.
256pub type SparseSet<T> = SparseMap<T, T>;
257
258#[cfg(test)]
259mod 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 {
274        fn key(&self) -> Inst {
275            self.0
276        }
277    }
278
279    #[test]
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]
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]
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]
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]
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]
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}