xref: /wasmtime-44.0.1/cranelift/entity/src/map.rs (revision bb8fa40e)
1747ad3c4Slazypassion //! Densely numbered entity references as mapping keys.
2747ad3c4Slazypassion 
3747ad3c4Slazypassion use crate::iter::{Iter, IterMut};
4747ad3c4Slazypassion use crate::keys::Keys;
5747ad3c4Slazypassion use crate::EntityRef;
6*bb8fa40eSbjorn3 use alloc::vec::Vec;
7a1f6457eSJoshua Nelson use core::cmp::min;
8747ad3c4Slazypassion use core::marker::PhantomData;
9747ad3c4Slazypassion use core::ops::{Index, IndexMut};
10747ad3c4Slazypassion use core::slice;
11d3815a03SArtur Jamro #[cfg(feature = "enable-serde")]
12d3815a03SArtur Jamro use serde::{
13d3815a03SArtur Jamro     de::{Deserializer, SeqAccess, Visitor},
14d3815a03SArtur Jamro     ser::{SerializeSeq, Serializer},
15d3815a03SArtur Jamro     Deserialize, Serialize,
16d3815a03SArtur Jamro };
17747ad3c4Slazypassion 
18747ad3c4Slazypassion /// A mapping `K -> V` for densely indexed entity references.
19747ad3c4Slazypassion ///
20747ad3c4Slazypassion /// The `SecondaryMap` data structure uses the dense index space to implement a map with a vector.
21747ad3c4Slazypassion /// Unlike `PrimaryMap`, an `SecondaryMap` can't be used to allocate entity references. It is used
22747ad3c4Slazypassion /// to associate secondary information with entities.
23747ad3c4Slazypassion ///
24747ad3c4Slazypassion /// The map does not track if an entry for a key has been inserted or not. Instead it behaves as if
25747ad3c4Slazypassion /// all keys have a default entry from the beginning.
26747ad3c4Slazypassion #[derive(Debug, Clone)]
27747ad3c4Slazypassion pub struct SecondaryMap<K, V>
28747ad3c4Slazypassion where
29747ad3c4Slazypassion     K: EntityRef,
30747ad3c4Slazypassion     V: Clone,
31747ad3c4Slazypassion {
32747ad3c4Slazypassion     elems: Vec<V>,
33747ad3c4Slazypassion     default: V,
34747ad3c4Slazypassion     unused: PhantomData<K>,
35747ad3c4Slazypassion }
36747ad3c4Slazypassion 
37747ad3c4Slazypassion /// Shared `SecondaryMap` implementation for all value types.
38747ad3c4Slazypassion impl<K, V> SecondaryMap<K, V>
39747ad3c4Slazypassion where
40747ad3c4Slazypassion     K: EntityRef,
41747ad3c4Slazypassion     V: Clone,
42747ad3c4Slazypassion {
43747ad3c4Slazypassion     /// Create a new empty map.
44747ad3c4Slazypassion     pub fn new() -> Self
45747ad3c4Slazypassion     where
46747ad3c4Slazypassion         V: Default,
47747ad3c4Slazypassion     {
48747ad3c4Slazypassion         Self {
49747ad3c4Slazypassion             elems: Vec::new(),
50747ad3c4Slazypassion             default: Default::default(),
51747ad3c4Slazypassion             unused: PhantomData,
52747ad3c4Slazypassion         }
53747ad3c4Slazypassion     }
54747ad3c4Slazypassion 
554b085b9cSSean Stangl     /// Create a new, empty map with the specified capacity.
564b085b9cSSean Stangl     ///
574b085b9cSSean Stangl     /// The map will be able to hold exactly `capacity` elements without reallocating.
584b085b9cSSean Stangl     pub fn with_capacity(capacity: usize) -> Self
594b085b9cSSean Stangl     where
604b085b9cSSean Stangl         V: Default,
614b085b9cSSean Stangl     {
624b085b9cSSean Stangl         Self {
634b085b9cSSean Stangl             elems: Vec::with_capacity(capacity),
644b085b9cSSean Stangl             default: Default::default(),
654b085b9cSSean Stangl             unused: PhantomData,
664b085b9cSSean Stangl         }
674b085b9cSSean Stangl     }
684b085b9cSSean Stangl 
69747ad3c4Slazypassion     /// Create a new empty map with a specified default value.
70747ad3c4Slazypassion     ///
71747ad3c4Slazypassion     /// This constructor does not require V to implement Default.
72747ad3c4Slazypassion     pub fn with_default(default: V) -> Self {
73747ad3c4Slazypassion         Self {
74747ad3c4Slazypassion             elems: Vec::new(),
75747ad3c4Slazypassion             default,
76747ad3c4Slazypassion             unused: PhantomData,
77747ad3c4Slazypassion         }
78747ad3c4Slazypassion     }
79747ad3c4Slazypassion 
804b085b9cSSean Stangl     /// Returns the number of elements the map can hold without reallocating.
814b085b9cSSean Stangl     pub fn capacity(&self) -> usize {
824b085b9cSSean Stangl         self.elems.capacity()
834b085b9cSSean Stangl     }
844b085b9cSSean Stangl 
85747ad3c4Slazypassion     /// Get the element at `k` if it exists.
8692a01c81Sjulian-seward1     #[inline(always)]
87747ad3c4Slazypassion     pub fn get(&self, k: K) -> Option<&V> {
88747ad3c4Slazypassion         self.elems.get(k.index())
89747ad3c4Slazypassion     }
90747ad3c4Slazypassion 
91747ad3c4Slazypassion     /// Is this map completely empty?
9292a01c81Sjulian-seward1     #[inline(always)]
93747ad3c4Slazypassion     pub fn is_empty(&self) -> bool {
94747ad3c4Slazypassion         self.elems.is_empty()
95747ad3c4Slazypassion     }
96747ad3c4Slazypassion 
97747ad3c4Slazypassion     /// Remove all entries from this map.
9892a01c81Sjulian-seward1     #[inline(always)]
99747ad3c4Slazypassion     pub fn clear(&mut self) {
100747ad3c4Slazypassion         self.elems.clear()
101747ad3c4Slazypassion     }
102747ad3c4Slazypassion 
103747ad3c4Slazypassion     /// Iterate over all the keys and values in this map.
104747ad3c4Slazypassion     pub fn iter(&self) -> Iter<K, V> {
105747ad3c4Slazypassion         Iter::new(self.elems.iter())
106747ad3c4Slazypassion     }
107747ad3c4Slazypassion 
108747ad3c4Slazypassion     /// Iterate over all the keys and values in this map, mutable edition.
109747ad3c4Slazypassion     pub fn iter_mut(&mut self) -> IterMut<K, V> {
110747ad3c4Slazypassion         IterMut::new(self.elems.iter_mut())
111747ad3c4Slazypassion     }
112747ad3c4Slazypassion 
113747ad3c4Slazypassion     /// Iterate over all the keys in this map.
114747ad3c4Slazypassion     pub fn keys(&self) -> Keys<K> {
115747ad3c4Slazypassion         Keys::with_len(self.elems.len())
116747ad3c4Slazypassion     }
117747ad3c4Slazypassion 
118747ad3c4Slazypassion     /// Iterate over all the values in this map.
119747ad3c4Slazypassion     pub fn values(&self) -> slice::Iter<V> {
120747ad3c4Slazypassion         self.elems.iter()
121747ad3c4Slazypassion     }
122747ad3c4Slazypassion 
123747ad3c4Slazypassion     /// Iterate over all the values in this map, mutable edition.
124747ad3c4Slazypassion     pub fn values_mut(&mut self) -> slice::IterMut<V> {
125747ad3c4Slazypassion         self.elems.iter_mut()
126747ad3c4Slazypassion     }
127747ad3c4Slazypassion 
128747ad3c4Slazypassion     /// Resize the map to have `n` entries by adding default entries as needed.
129747ad3c4Slazypassion     pub fn resize(&mut self, n: usize) {
130747ad3c4Slazypassion         self.elems.resize(n, self.default.clone());
131747ad3c4Slazypassion     }
132747ad3c4Slazypassion }
133747ad3c4Slazypassion 
134747ad3c4Slazypassion /// Immutable indexing into an `SecondaryMap`.
135747ad3c4Slazypassion ///
136747ad3c4Slazypassion /// All keys are permitted. Untouched entries have the default value.
137747ad3c4Slazypassion impl<K, V> Index<K> for SecondaryMap<K, V>
138747ad3c4Slazypassion where
139747ad3c4Slazypassion     K: EntityRef,
140747ad3c4Slazypassion     V: Clone,
141747ad3c4Slazypassion {
142747ad3c4Slazypassion     type Output = V;
143747ad3c4Slazypassion 
14492a01c81Sjulian-seward1     #[inline(always)]
145747ad3c4Slazypassion     fn index(&self, k: K) -> &V {
14692a01c81Sjulian-seward1         self.elems.get(k.index()).unwrap_or(&self.default)
147747ad3c4Slazypassion     }
148747ad3c4Slazypassion }
149747ad3c4Slazypassion 
150747ad3c4Slazypassion /// Mutable indexing into an `SecondaryMap`.
151747ad3c4Slazypassion ///
152747ad3c4Slazypassion /// The map grows as needed to accommodate new keys.
153747ad3c4Slazypassion impl<K, V> IndexMut<K> for SecondaryMap<K, V>
154747ad3c4Slazypassion where
155747ad3c4Slazypassion     K: EntityRef,
156747ad3c4Slazypassion     V: Clone,
157747ad3c4Slazypassion {
15892a01c81Sjulian-seward1     #[inline(always)]
159747ad3c4Slazypassion     fn index_mut(&mut self, k: K) -> &mut V {
160747ad3c4Slazypassion         let i = k.index();
161747ad3c4Slazypassion         if i >= self.elems.len() {
16292a01c81Sjulian-seward1             self.elems.resize(i + 1, self.default.clone());
163747ad3c4Slazypassion         }
164747ad3c4Slazypassion         &mut self.elems[i]
165747ad3c4Slazypassion     }
166747ad3c4Slazypassion }
167747ad3c4Slazypassion 
168d3815a03SArtur Jamro impl<K, V> PartialEq for SecondaryMap<K, V>
169d3815a03SArtur Jamro where
170d3815a03SArtur Jamro     K: EntityRef,
171d3815a03SArtur Jamro     V: Clone + PartialEq,
172d3815a03SArtur Jamro {
173d3815a03SArtur Jamro     fn eq(&self, other: &Self) -> bool {
174d3815a03SArtur Jamro         let min_size = min(self.elems.len(), other.elems.len());
175d3815a03SArtur Jamro         self.default == other.default
176d3815a03SArtur Jamro             && self.elems[..min_size] == other.elems[..min_size]
177d3815a03SArtur Jamro             && self.elems[min_size..].iter().all(|e| *e == self.default)
178d3815a03SArtur Jamro             && other.elems[min_size..].iter().all(|e| *e == other.default)
179d3815a03SArtur Jamro     }
180d3815a03SArtur Jamro }
181d3815a03SArtur Jamro 
182d3815a03SArtur Jamro impl<K, V> Eq for SecondaryMap<K, V>
183d3815a03SArtur Jamro where
184d3815a03SArtur Jamro     K: EntityRef,
185d3815a03SArtur Jamro     V: Clone + PartialEq + Eq,
186d3815a03SArtur Jamro {
187d3815a03SArtur Jamro }
188d3815a03SArtur Jamro 
189d3815a03SArtur Jamro #[cfg(feature = "enable-serde")]
190d3815a03SArtur Jamro impl<K, V> Serialize for SecondaryMap<K, V>
191d3815a03SArtur Jamro where
192d3815a03SArtur Jamro     K: EntityRef,
193d3815a03SArtur Jamro     V: Clone + PartialEq + Serialize,
194d3815a03SArtur Jamro {
195d3815a03SArtur Jamro     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
196d3815a03SArtur Jamro     where
197d3815a03SArtur Jamro         S: Serializer,
198d3815a03SArtur Jamro     {
199d3815a03SArtur Jamro         // TODO: bincode encodes option as "byte for Some/None" and then optionally the content
200d3815a03SArtur Jamro         // TODO: we can actually optimize it by encoding manually bitmask, then elements
201d3815a03SArtur Jamro         let mut elems_cnt = self.elems.len();
202d3815a03SArtur Jamro         while elems_cnt > 0 && self.elems[elems_cnt - 1] == self.default {
203d3815a03SArtur Jamro             elems_cnt -= 1;
204d3815a03SArtur Jamro         }
205d3815a03SArtur Jamro         let mut seq = serializer.serialize_seq(Some(1 + elems_cnt))?;
206d3815a03SArtur Jamro         seq.serialize_element(&Some(self.default.clone()))?;
207d3815a03SArtur Jamro         for e in self.elems.iter().take(elems_cnt) {
208d3815a03SArtur Jamro             let some_e = Some(e);
209d3815a03SArtur Jamro             seq.serialize_element(if *e == self.default { &None } else { &some_e })?;
210d3815a03SArtur Jamro         }
211d3815a03SArtur Jamro         seq.end()
212d3815a03SArtur Jamro     }
213d3815a03SArtur Jamro }
214d3815a03SArtur Jamro 
215d3815a03SArtur Jamro #[cfg(feature = "enable-serde")]
216d3815a03SArtur Jamro impl<'de, K, V> Deserialize<'de> for SecondaryMap<K, V>
217d3815a03SArtur Jamro where
218d3815a03SArtur Jamro     K: EntityRef,
219d3815a03SArtur Jamro     V: Clone + Deserialize<'de>,
220d3815a03SArtur Jamro {
221d3815a03SArtur Jamro     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
222d3815a03SArtur Jamro     where
223d3815a03SArtur Jamro         D: Deserializer<'de>,
224d3815a03SArtur Jamro     {
225a114423dSbjorn3         use alloc::fmt;
226d3815a03SArtur Jamro         struct SecondaryMapVisitor<K, V> {
227d3815a03SArtur Jamro             unused: PhantomData<fn(K) -> V>,
228d3815a03SArtur Jamro         }
229d3815a03SArtur Jamro 
230d3815a03SArtur Jamro         impl<'de, K, V> Visitor<'de> for SecondaryMapVisitor<K, V>
231d3815a03SArtur Jamro         where
232d3815a03SArtur Jamro             K: EntityRef,
233d3815a03SArtur Jamro             V: Clone + Deserialize<'de>,
234d3815a03SArtur Jamro         {
235d3815a03SArtur Jamro             type Value = SecondaryMap<K, V>;
236d3815a03SArtur Jamro 
237d3815a03SArtur Jamro             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
238d3815a03SArtur Jamro                 formatter.write_str("struct SecondaryMap")
239d3815a03SArtur Jamro             }
240d3815a03SArtur Jamro 
241d3815a03SArtur Jamro             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
242d3815a03SArtur Jamro             where
243d3815a03SArtur Jamro                 A: SeqAccess<'de>,
244d3815a03SArtur Jamro             {
245d3815a03SArtur Jamro                 match seq.next_element()? {
246d3815a03SArtur Jamro                     Some(Some(default_val)) => {
247d3815a03SArtur Jamro                         let default_val: V = default_val; // compiler can't infer the type
248d3815a03SArtur Jamro                         let mut m = SecondaryMap::with_default(default_val.clone());
249d3815a03SArtur Jamro                         let mut idx = 0;
250d3815a03SArtur Jamro                         while let Some(val) = seq.next_element()? {
251d3815a03SArtur Jamro                             let val: Option<_> = val; // compiler can't infer the type
252d3815a03SArtur Jamro                             m[K::new(idx)] = val.unwrap_or_else(|| default_val.clone());
253d3815a03SArtur Jamro                             idx += 1;
254d3815a03SArtur Jamro                         }
255d3815a03SArtur Jamro                         Ok(m)
256d3815a03SArtur Jamro                     }
257d3815a03SArtur Jamro                     _ => Err(serde::de::Error::custom("Default value required")),
258d3815a03SArtur Jamro                 }
259d3815a03SArtur Jamro             }
260d3815a03SArtur Jamro         }
261d3815a03SArtur Jamro 
262d3815a03SArtur Jamro         deserializer.deserialize_seq(SecondaryMapVisitor {
263d3815a03SArtur Jamro             unused: PhantomData {},
264d3815a03SArtur Jamro         })
265d3815a03SArtur Jamro     }
266d3815a03SArtur Jamro }
267d3815a03SArtur Jamro 
268747ad3c4Slazypassion #[cfg(test)]
269747ad3c4Slazypassion mod tests {
270747ad3c4Slazypassion     use super::*;
271747ad3c4Slazypassion 
272747ad3c4Slazypassion     // `EntityRef` impl for testing.
273747ad3c4Slazypassion     #[derive(Clone, Copy, Debug, PartialEq, Eq)]
274747ad3c4Slazypassion     struct E(u32);
275747ad3c4Slazypassion 
276747ad3c4Slazypassion     impl EntityRef for E {
277747ad3c4Slazypassion         fn new(i: usize) -> Self {
278747ad3c4Slazypassion             E(i as u32)
279747ad3c4Slazypassion         }
280747ad3c4Slazypassion         fn index(self) -> usize {
281747ad3c4Slazypassion             self.0 as usize
282747ad3c4Slazypassion         }
283747ad3c4Slazypassion     }
284747ad3c4Slazypassion 
285747ad3c4Slazypassion     #[test]
286747ad3c4Slazypassion     fn basic() {
287747ad3c4Slazypassion         let r0 = E(0);
288747ad3c4Slazypassion         let r1 = E(1);
289747ad3c4Slazypassion         let r2 = E(2);
290747ad3c4Slazypassion         let mut m = SecondaryMap::new();
291747ad3c4Slazypassion 
292747ad3c4Slazypassion         let v: Vec<E> = m.keys().collect();
293747ad3c4Slazypassion         assert_eq!(v, []);
294747ad3c4Slazypassion 
295747ad3c4Slazypassion         m[r2] = 3;
296747ad3c4Slazypassion         m[r1] = 5;
297747ad3c4Slazypassion 
298747ad3c4Slazypassion         assert_eq!(m[r1], 5);
299747ad3c4Slazypassion         assert_eq!(m[r2], 3);
300747ad3c4Slazypassion 
301747ad3c4Slazypassion         let v: Vec<E> = m.keys().collect();
302747ad3c4Slazypassion         assert_eq!(v, [r0, r1, r2]);
303747ad3c4Slazypassion 
304747ad3c4Slazypassion         let shared = &m;
305747ad3c4Slazypassion         assert_eq!(shared[r0], 0);
306747ad3c4Slazypassion         assert_eq!(shared[r1], 5);
307747ad3c4Slazypassion         assert_eq!(shared[r2], 3);
308747ad3c4Slazypassion     }
309747ad3c4Slazypassion }
310