Skip to main content

ordinal_map/map/
map.rs

1use std::fmt;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4
5use crate::map::iter::ValuesMut;
6use crate::map::total;
7use crate::map::Drain;
8use crate::map::Entry;
9use crate::map::IntoIter;
10use crate::map::Iter;
11use crate::map::IterMut;
12use crate::map::Keys;
13use crate::map::Values;
14use crate::Ordinal;
15
16/// Map [`Ordinal`](crate::Ordinal) keys to values.
17/// Map operations are constant time
18/// (provided that [`K::ordinal()`](Ordinal::ordinal) is constant time).
19///
20/// This implementation allocates a boxed slice `[Option<V>; K::ORDINAL_SIZE]`
21/// on the first insertion. For non-allocating map, consider using
22/// [`OrdinalArrayMap`](crate::map::OrdinalArrayMap).
23///
24/// This implementation is sparse (not every key has an associated value).
25/// For a total map, see [`OrdinalTotalMap`](total::OrdinalTotalMap)
26/// and [`OrdinalTotalArrayMap`](total::OrdinalTotalArrayMap).
27pub struct OrdinalMap<K, V> {
28    // Empty when the map is just created.
29    map: Box<[Option<V>]>,
30    _phantom: PhantomData<K>,
31}
32
33impl<K: Ordinal, V> OrdinalMap<K, V> {
34    /// Create a new empty map.
35    /// This operation does not allocate memory, but first insertion allocates the whole map.
36    #[inline]
37    pub fn new() -> Self {
38        OrdinalMap {
39            map: Box::default(),
40            _phantom: PhantomData,
41        }
42    }
43
44    /// Returns a reference to the value corresponding to the key.
45    #[inline]
46    pub fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
47        self.map.get(key.ordinal())?.as_ref()
48    }
49
50    /// Returns a mutable reference to the value corresponding to the key.
51    #[inline]
52    pub fn get_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
53        self.map.get_mut(key.ordinal())?.as_mut()
54    }
55
56    /// Returns `true` if the map contains the key.
57    #[inline]
58    pub fn contains_key(&self, key: &K) -> bool {
59        self.map.get(key.ordinal()).is_some()
60    }
61
62    /// Returns the number of elements in the map. This is an `O(K::ORDINAL_SIZE)` operation.
63    #[inline]
64    pub fn len(&self) -> usize {
65        self.iter().count()
66    }
67
68    /// Return true if the map container no elements.
69    #[inline]
70    pub fn is_empty(&self) -> bool {
71        self.iter().next().is_none()
72    }
73
74    fn init_full_map(&mut self) {
75        if self.map.is_empty() {
76            let mut map = Vec::with_capacity(K::ORDINAL_SIZE);
77            for _ in 0..K::ORDINAL_SIZE {
78                map.push(None);
79            }
80            self.map = map.into_boxed_slice();
81        }
82    }
83
84    /// Insert a value into the map, returning the previous value if it existed.
85    #[inline]
86    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
87        self.init_full_map();
88        self.map[key.ordinal()].replace(value)
89    }
90
91    /// Get an entry in the map for the given key.
92    pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
93        self.init_full_map();
94        let entry = &mut self.map[key.ordinal()];
95        Entry::new(key, entry)
96    }
97
98    /// Remove a value from the map, returning it if it existed.
99    #[inline]
100    pub fn remove(&mut self, key: &K) -> Option<V> {
101        self.map.get_mut(key.ordinal())?.take()
102    }
103
104    /// Iterate over the map.
105    #[inline]
106    pub fn iter(&self) -> Iter<'_, K, V> {
107        Iter::new(total::Iter::new(self.map.iter(), 0))
108    }
109
110    /// Iterate over the map mutably.
111    #[inline]
112    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
113        IterMut::new(total::IterMut::new(self.map.iter_mut()))
114    }
115
116    /// Iterate over the keys of the map.
117    #[inline]
118    pub fn keys(&self) -> Keys<'_, K, V> {
119        Keys::new(self.iter())
120    }
121
122    /// Iterate over the values of the map.
123    #[inline]
124    pub fn values(&self) -> Values<'_, K, V> {
125        Values::new(self.iter())
126    }
127
128    /// Iterate over the mutable references to the values of the map.
129    #[inline]
130    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
131        ValuesMut::new(self.iter_mut())
132    }
133
134    /// Clears the map, returning all key-value pairs as an iterator.
135    #[inline]
136    pub fn drain(&mut self) -> Drain<'_, K, V> {
137        Drain::new(total::IterMut::new(self.map.iter_mut()))
138    }
139
140    /// Remove all elements from the map.
141    #[inline]
142    pub fn clear(&mut self) {
143        self.drain();
144    }
145}
146
147impl<K: Ordinal, V> Default for OrdinalMap<K, V> {
148    #[inline]
149    fn default() -> Self {
150        Self::new()
151    }
152}
153
154impl<K: Ordinal, V> FromIterator<(K, V)> for OrdinalMap<K, V> {
155    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
156        let mut map = OrdinalMap::new();
157        for (k, v) in iter {
158            map.insert(k, v);
159        }
160        map
161    }
162}
163
164impl<K, V: Clone> Clone for OrdinalMap<K, V> {
165    fn clone(&self) -> Self {
166        OrdinalMap {
167            map: self.map.clone(),
168            _phantom: PhantomData,
169        }
170    }
171}
172
173impl<K: Ordinal + Debug, V: Debug> Debug for OrdinalMap<K, V> {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        f.debug_map().entries(self.iter()).finish()
176    }
177}
178
179impl<K: Ordinal, V> IntoIterator for OrdinalMap<K, V> {
180    type Item = (K, V);
181    type IntoIter = IntoIter<K, V>;
182
183    #[inline]
184    fn into_iter(self) -> Self::IntoIter {
185        IntoIter::new(total::IntoIter::new(self.map.into_vec().into_iter()))
186    }
187}
188
189impl<'a, K: Ordinal, V> IntoIterator for &'a OrdinalMap<K, V> {
190    type Item = (K, &'a V);
191    type IntoIter = Iter<'a, K, V>;
192
193    #[inline]
194    fn into_iter(self) -> Self::IntoIter {
195        self.iter()
196    }
197}
198
199#[cfg(test)]
200mod tests {
201    use std::collections::HashMap;
202
203    use crate::map::OrdinalMap;
204
205    #[quickcheck]
206    fn qc(values: Vec<(u8, u32)>, check: Vec<u8>) {
207        let mut map: OrdinalMap<u8, u32> = OrdinalMap::new();
208        let mut control: HashMap<u8, u32> = HashMap::new();
209
210        for (key, value) in &values {
211            let control_inserted = control.insert(*key, *value);
212            let inserted = map.insert(*key, *value);
213            assert_eq!(control_inserted, inserted);
214            assert_eq!(control.len(), map.len());
215        }
216
217        for key in &check {
218            assert_eq!(control.get(key), map.get(key));
219        }
220    }
221}