Skip to main content

wasmtime_environ/collections/
btree_map.rs

1//! OOM-handling `TryBTreeMap` implementation.
2
3use crate::error::OutOfMemory;
4use core::{mem, ops::RangeBounds, ptr::NonNull};
5use wasmtime_core::slab::{Id, Slab};
6
7/// Like `std::collections::BTreeMap` but its methods return errors on
8/// allocation failure.
9pub struct TryBTreeMap<K, V>
10where
11    K: Copy,
12{
13    values: Slab<V>,
14    forest: cranelift_bforest::MapForest<K, Id>,
15    map: cranelift_bforest::Map<K, Id>,
16}
17
18impl<K, V> core::fmt::Debug for TryBTreeMap<K, V>
19where
20    K: Copy + Ord + core::fmt::Debug,
21    V: core::fmt::Debug,
22{
23    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24        f.debug_map().entries(self.iter()).finish()
25    }
26}
27
28impl<K, V> Default for TryBTreeMap<K, V>
29where
30    K: Copy,
31{
32    fn default() -> Self {
33        Self {
34            values: Default::default(),
35            forest: cranelift_bforest::MapForest::new(),
36            map: Default::default(),
37        }
38    }
39}
40
41impl<K, V> TryBTreeMap<K, V>
42where
43    K: Copy,
44{
45    /// Same as [`std::collections::BTreeMap::new`].
46    pub fn new() -> Self {
47        Self::default()
48    }
49
50    /// Same as [`std::collections::BTreeMap::len`].
51    pub fn len(&self) -> usize {
52        self.values.len()
53    }
54
55    /// Same as [`std::collections::BTreeMap::is_empty`].
56    pub fn is_empty(&self) -> bool {
57        self.map.is_empty()
58    }
59
60    fn get_id(&self, key: K) -> Option<Id>
61    where
62        K: Ord,
63    {
64        self.map.get(key, &self.forest, &())
65    }
66
67    /// Same as [`std::collections::BTreeMap::contains_key`].
68    pub fn contains_key(&self, key: K) -> bool
69    where
70        K: Ord,
71    {
72        self.get_id(key).is_some()
73    }
74
75    /// Same as [`std::collections::BTreeMap::get`].
76    pub fn get(&self, key: K) -> Option<&V>
77    where
78        K: Ord,
79    {
80        let id = self.get_id(key)?;
81        Some(&self.values[id])
82    }
83
84    /// Same as [`std::collections::BTreeMap::get_mut`].
85    pub fn get_mut(&mut self, key: K) -> Option<&mut V>
86    where
87        K: Ord,
88    {
89        let id = self.get_id(key)?;
90        Some(&mut self.values[id])
91    }
92
93    /// Same as [`std::collections::BTreeMap::insert`] but returns an error on
94    /// allocation failure.
95    pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, OutOfMemory>
96    where
97        K: Ord,
98    {
99        if let Some(id) = self.get_id(key) {
100            return Ok(Some(mem::replace(&mut self.values[id], value)));
101        }
102
103        let id = self.values.alloc(value)?;
104        match self.map.try_insert(key, id, &mut self.forest, &()) {
105            Ok(old) => {
106                debug_assert!(old.is_none());
107                Ok(None)
108            }
109            Err(oom) => {
110                self.values.dealloc(id);
111                Err(oom)
112            }
113        }
114    }
115
116    /// Same as [`std::collections::BTreeMap::remove`].
117    pub fn remove(&mut self, key: K) -> Option<V>
118    where
119        K: Ord,
120    {
121        let id = self.map.remove(key, &mut self.forest, &())?;
122        Some(self.values.dealloc(id))
123    }
124
125    /// Same as [`std::collections::BTreeMap::clear`].
126    ///
127    /// Does not deallocate the underlying storage.
128    pub fn clear(&mut self) {
129        self.values.clear();
130        // NB: Do not do `self.map.clear(&mut self.forest)` because that is
131        // designed to work in scenarios where multiple maps are sharing the
132        // same forest (which we are not doing here) and will actually traverse
133        // the b-tree's nodes and deallocate each of them one at a time. For our
134        // single-map-in-the-forest case, it is equivalent, but much faster, to
135        // simply clear the forest itself and reset the map to its default,
136        // empty state.
137        self.forest.clear();
138        self.map = Default::default();
139    }
140
141    /// Same as [`std::collections::BTreeMap::iter`].
142    pub fn iter(&self) -> BTreeMapIter<'_, K, V> {
143        BTreeMapIter {
144            inner: self.map.iter(&self.forest),
145            values: &self.values,
146        }
147    }
148
149    /// Same as [`std::collections::BTreeMap::iter`].
150    pub fn iter_mut(&mut self) -> BTreeMapIterMut<'_, K, V> {
151        BTreeMapIterMut {
152            inner: self.map.iter(&self.forest),
153            values: &mut self.values,
154        }
155    }
156
157    /// Same as [`std::collections::BTreeMap::keys`].
158    pub fn keys(&self) -> BTreeMapKeys<'_, K, V> {
159        BTreeMapKeys { inner: self.iter() }
160    }
161
162    /// Same as [`std::collections::BTreeMap::values`].
163    pub fn values(&self) -> BTreeMapValues<'_, K, V> {
164        BTreeMapValues { inner: self.iter() }
165    }
166
167    /// Same as [`std::collections::BTreeMap::values_mut`].
168    pub fn values_mut(&mut self) -> BTreeMapValuesMut<'_, K, V> {
169        BTreeMapValuesMut {
170            inner: self.iter_mut(),
171        }
172    }
173
174    /// Same as [`std::collections::BTreeMap::range`].
175    pub fn range<R>(&self, range: R) -> BTreeMapRange<'_, K, V>
176    where
177        K: Ord,
178        R: RangeBounds<K>,
179    {
180        BTreeMapRange {
181            inner: self.map.range(range, &self.forest, &()),
182            values: &self.values,
183        }
184    }
185
186    /// Same as [`std::collections::BTreeMap::range_mut`].
187    pub fn range_mut<R>(&mut self, range: R) -> BTreeMapRangeMut<'_, K, V>
188    where
189        K: Ord,
190        R: RangeBounds<K>,
191    {
192        BTreeMapRangeMut {
193            inner: self.map.range(range, &self.forest, &()),
194            values: &mut self.values,
195        }
196    }
197
198    /// Same as [`std::collections::BTreeMap::entry`].
199    pub fn entry(&mut self, key: K) -> Entry<'_, K, V>
200    where
201        K: Ord,
202    {
203        let mut cursor = self.map.cursor_mut(&mut self.forest, &());
204        match cursor.goto(key) {
205            Some(_) => Entry::Occupied(OccupiedEntry {
206                cursor,
207                values: &mut self.values,
208            }),
209            None => Entry::Vacant(VacantEntry {
210                key,
211                cursor,
212                values: &mut self.values,
213            }),
214        }
215    }
216}
217
218impl<'a, K, V> IntoIterator for &'a TryBTreeMap<K, V>
219where
220    K: Copy,
221{
222    type Item = (K, &'a V);
223    type IntoIter = BTreeMapIter<'a, K, V>;
224
225    fn into_iter(self) -> Self::IntoIter {
226        self.iter()
227    }
228}
229
230/// An iterator over `(K, &V)` pairs returned by [`TryBTreeMap::iter`].
231pub struct BTreeMapIter<'a, K, V>
232where
233    K: Copy,
234{
235    inner: cranelift_bforest::MapIter<'a, K, Id>,
236    values: &'a Slab<V>,
237}
238
239impl<'a, K, V> Iterator for BTreeMapIter<'a, K, V>
240where
241    K: Copy,
242{
243    type Item = (K, &'a V);
244
245    fn next(&mut self) -> Option<Self::Item> {
246        let (key, id) = self.inner.next()?;
247        Some((key, &self.values[id]))
248    }
249
250    fn size_hint(&self) -> (usize, Option<usize>) {
251        self.inner.size_hint()
252    }
253}
254
255impl<'a, K, V> IntoIterator for &'a mut TryBTreeMap<K, V>
256where
257    K: Copy,
258{
259    type Item = (K, &'a mut V);
260    type IntoIter = BTreeMapIterMut<'a, K, V>;
261
262    fn into_iter(self) -> Self::IntoIter {
263        self.iter_mut()
264    }
265}
266
267/// An iterator over `(K, &mut V)` pairs returned by [`TryBTreeMap::iter_mut`].
268pub struct BTreeMapIterMut<'a, K, V>
269where
270    K: Copy,
271{
272    inner: cranelift_bforest::MapIter<'a, K, Id>,
273    values: &'a mut Slab<V>,
274}
275
276impl<'a, K, V> Iterator for BTreeMapIterMut<'a, K, V>
277where
278    K: Copy,
279{
280    type Item = (K, &'a mut V);
281
282    fn next(&mut self) -> Option<Self::Item> {
283        let (key, id) = self.inner.next()?;
284        let val = &mut self.values[id];
285
286        // Safety: It is okay to extend the borrow from `&'1 mut self` to `&'a`
287        // because each entry is associated with a unique `id` and we will never
288        // return multiple mutable borrows of the same value.
289        let val = unsafe { NonNull::from(val).as_mut() };
290
291        Some((key, val))
292    }
293
294    fn size_hint(&self) -> (usize, Option<usize>) {
295        self.inner.size_hint()
296    }
297}
298
299impl<K, V> IntoIterator for TryBTreeMap<K, V>
300where
301    K: Copy + Ord,
302{
303    type Item = (K, V);
304    type IntoIter = BTreeMapIntoIter<K, V>;
305
306    fn into_iter(self) -> Self::IntoIter {
307        BTreeMapIntoIter {
308            inner: self.map.into_iter(self.forest),
309            values: self.values,
310        }
311    }
312}
313
314/// An iterator over `(K, V)` pairs returned by [`TryBTreeMap::into_iter`].
315pub struct BTreeMapIntoIter<K, V>
316where
317    K: Copy,
318{
319    inner: cranelift_bforest::MapIntoIter<K, Id>,
320    values: Slab<V>,
321}
322
323impl<K, V> Iterator for BTreeMapIntoIter<K, V>
324where
325    K: Copy + Ord,
326{
327    type Item = (K, V);
328
329    fn next(&mut self) -> Option<Self::Item> {
330        let (key, id) = self.inner.next()?;
331        let value = self.values.dealloc(id);
332        Some((key, value))
333    }
334
335    fn size_hint(&self) -> (usize, Option<usize>) {
336        let len = self.values.len();
337        (len, Some(len))
338    }
339}
340
341/// An iterator over keys returned by [`TryBTreeMap::keys`].
342pub struct BTreeMapKeys<'a, K, V>
343where
344    K: Copy,
345{
346    inner: BTreeMapIter<'a, K, V>,
347}
348
349impl<'a, K, V> Iterator for BTreeMapKeys<'a, K, V>
350where
351    K: Copy,
352{
353    type Item = K;
354
355    fn next(&mut self) -> Option<Self::Item> {
356        let (k, _v) = self.inner.next()?;
357        Some(k)
358    }
359}
360
361/// An iterator over shared values returned by [`TryBTreeMap::values`].
362pub struct BTreeMapValues<'a, K, V>
363where
364    K: Copy,
365{
366    inner: BTreeMapIter<'a, K, V>,
367}
368
369impl<'a, K, V> Iterator for BTreeMapValues<'a, K, V>
370where
371    K: Copy,
372{
373    type Item = &'a V;
374
375    fn next(&mut self) -> Option<Self::Item> {
376        let (_k, v) = self.inner.next()?;
377        Some(v)
378    }
379}
380
381/// An iterator over mutable values returned by [`TryBTreeMap::values_mut`].
382pub struct BTreeMapValuesMut<'a, K, V>
383where
384    K: Copy,
385{
386    inner: BTreeMapIterMut<'a, K, V>,
387}
388
389impl<'a, K, V> Iterator for BTreeMapValuesMut<'a, K, V>
390where
391    K: Copy,
392{
393    type Item = &'a mut V;
394
395    fn next(&mut self) -> Option<Self::Item> {
396        let (_k, v) = self.inner.next()?;
397        Some(v)
398    }
399}
400
401/// A range iterator of `(K, &'a V)` items returned by [`TryBTreeMap::range`].
402pub struct BTreeMapRange<'a, K, V>
403where
404    K: Copy + Ord,
405{
406    inner: cranelift_bforest::MapRange<'a, K, Id, ()>,
407    values: &'a Slab<V>,
408}
409
410impl<'a, K, V> Iterator for BTreeMapRange<'a, K, V>
411where
412    K: Copy + Ord,
413{
414    type Item = (K, &'a V);
415
416    fn next(&mut self) -> Option<Self::Item> {
417        let (key, id) = self.inner.next()?;
418        Some((key, &self.values[id]))
419    }
420}
421
422impl<'a, K, V> DoubleEndedIterator for BTreeMapRange<'a, K, V>
423where
424    K: Copy + Ord,
425{
426    fn next_back(&mut self) -> Option<Self::Item> {
427        let (key, id) = self.inner.next_back()?;
428        Some((key, &self.values[id]))
429    }
430}
431
432/// A range iterator of `(K, &'a V)` items returned by [`TryBTreeMap::range`].
433pub struct BTreeMapRangeMut<'a, K, V>
434where
435    K: Copy + Ord,
436{
437    inner: cranelift_bforest::MapRange<'a, K, Id, ()>,
438    values: &'a mut Slab<V>,
439}
440
441impl<'a, K, V> Iterator for BTreeMapRangeMut<'a, K, V>
442where
443    K: Copy + Ord,
444{
445    type Item = (K, &'a mut V);
446
447    fn next(&mut self) -> Option<Self::Item> {
448        let (key, id) = self.inner.next()?;
449        let val = &mut self.values[id];
450
451        // Safety: It is okay to extend the borrow from `&'1 mut self` to `&'a`
452        // because each entry is associated with a unique `id` and we will never
453        // return multiple mutable borrows of the same value.
454        let val = unsafe { NonNull::from(val).as_mut() };
455
456        Some((key, val))
457    }
458}
459
460/// Same as [`std::collections::btree_map::Entry`].
461#[allow(missing_docs, reason = "self explanatory")]
462pub enum Entry<'a, K, V>
463where
464    K: Copy + Ord,
465{
466    Occupied(OccupiedEntry<'a, K, V>),
467    Vacant(VacantEntry<'a, K, V>),
468}
469
470impl<'a, K, V> Entry<'a, K, V>
471where
472    K: Copy + Ord,
473{
474    /// Same as [`std::collections::btree_map::Entry::or_insert`] but returns an
475    /// error on allocation failure.
476    pub fn or_insert(self, default: V) -> Result<&'a mut V, OutOfMemory> {
477        self.or_insert_with(|| default)
478    }
479
480    /// Same as [`std::collections::btree_map::Entry::or_insert_with`] but
481    /// returns an error on allocation failure.
482    pub fn or_insert_with<F>(self, default: F) -> Result<&'a mut V, OutOfMemory>
483    where
484        F: FnOnce() -> V,
485    {
486        self.or_insert_with_key(|_| default())
487    }
488
489    /// Same as [`std::collections::btree_map::Entry::or_insert_with_key`] but
490    /// returns an error on allocation failure.
491    pub fn or_insert_with_key<F>(self, default: F) -> Result<&'a mut V, OutOfMemory>
492    where
493        F: FnOnce(K) -> V,
494    {
495        match self {
496            Entry::Occupied(e) => {
497                let id = e.cursor.value().unwrap();
498                Ok(&mut e.values[id])
499            }
500            Entry::Vacant(mut e) => {
501                let id = e.values.alloc(default(e.key))?;
502                match e.cursor.try_insert(e.key, id) {
503                    Ok(old) => {
504                        debug_assert!(old.is_none());
505                        Ok(&mut e.values[id])
506                    }
507                    Err(oom) => {
508                        e.values.dealloc(id);
509                        Err(oom)
510                    }
511                }
512            }
513        }
514    }
515
516    /// Same as [`std::collections::btree_map::Entry::key`].
517    pub fn key(&self) -> K {
518        match self {
519            Entry::Occupied(e) => e.cursor.key().unwrap(),
520            Entry::Vacant(e) => e.key,
521        }
522    }
523
524    /// Same as [`std::collections::btree_map::Entry::and_modify`].
525    pub fn and_modify<F>(self, f: F) -> Self
526    where
527        F: FnOnce(&mut V),
528    {
529        match self {
530            Entry::Occupied(mut e) => {
531                f(e.get_mut());
532                Entry::Occupied(e)
533            }
534            e @ Entry::Vacant(_) => e,
535        }
536    }
537
538    /// Same as [`std::collections::btree_map::Entry::and_modify`] but returns
539    /// an error on allocation failure.
540    pub fn insert_entry(self, value: V) -> Result<OccupiedEntry<'a, K, V>, OutOfMemory> {
541        match self {
542            Entry::Occupied(e) => Ok(e),
543            Entry::Vacant(e) => e.insert_entry(value),
544        }
545    }
546
547    /// Same as [`std::collections::btree_map::Entry::or_default`] but returns
548    /// an error on allocation failure.
549    pub fn or_default(self) -> Result<&'a mut V, OutOfMemory>
550    where
551        V: Default,
552    {
553        self.or_insert_with(Default::default)
554    }
555}
556
557/// Same as [`std::collections::btree_map::OccupiedEntry`].
558pub struct OccupiedEntry<'a, K, V>
559where
560    K: Copy + Ord,
561{
562    cursor: cranelift_bforest::MapCursorMut<'a, K, Id, ()>,
563    values: &'a mut Slab<V>,
564}
565
566impl<'a, K, V> OccupiedEntry<'a, K, V>
567where
568    K: Copy + Ord,
569{
570    /// Same as [`std::collections::btree_map::OccupiedEntry::key`].
571    pub fn key(&self) -> K {
572        self.cursor.key().unwrap()
573    }
574
575    /// Same as [`std::collections::btree_map::OccupiedEntry::remove_entry`].
576    pub fn remove_entry(mut self) -> (K, V) {
577        let key = self.key();
578        let id = self.cursor.remove().unwrap();
579        let value = self.values.dealloc(id);
580        (key, value)
581    }
582
583    /// Same as [`std::collections::btree_map::OccupiedEntry::get`].
584    pub fn get(&self) -> &V {
585        let id = self.cursor.value().unwrap();
586        &self.values[id]
587    }
588
589    /// Same as [`std::collections::btree_map::OccupiedEntry::get_mut`].
590    pub fn get_mut(&mut self) -> &mut V {
591        let id = self.cursor.value().unwrap();
592        &mut self.values[id]
593    }
594
595    /// Same as [`std::collections::btree_map::OccupiedEntry::into_mut`].
596    pub fn into_mut(self) -> &'a mut V {
597        let id = self.cursor.value().unwrap();
598        &mut self.values[id]
599    }
600
601    /// Same as [`std::collections::btree_map::OccupiedEntry::insert`].
602    pub fn insert(self, value: V) -> V {
603        let id = self.cursor.value().unwrap();
604        mem::replace(&mut self.values[id], value)
605    }
606
607    /// Same as [`std::collections::btree_map::OccupiedEntry::remove`].
608    pub fn remove(mut self) -> V {
609        let id = self.cursor.remove().unwrap();
610        self.values.dealloc(id)
611    }
612}
613
614/// Same as [`std::collections::btree_map::VacantEntry`].
615pub struct VacantEntry<'a, K, V>
616where
617    K: Copy + Ord,
618{
619    key: K,
620    cursor: cranelift_bforest::MapCursorMut<'a, K, Id, ()>,
621    values: &'a mut Slab<V>,
622}
623
624impl<'a, K, V> VacantEntry<'a, K, V>
625where
626    K: Copy + Ord,
627{
628    /// Same as [`std::collections::btree_map::VacantEntry::key`].
629    pub fn key(&self) -> K {
630        self.key
631    }
632
633    /// Same as [`std::collections::btree_map::VacantEntry::into_key`].
634    pub fn into_key(self) -> K {
635        self.key
636    }
637
638    /// Same as [`std::collections::btree_map::VacantEntry::insert`] but returns
639    /// an error on allocation failure.
640    pub fn insert(self, value: V) -> Result<&'a mut V, OutOfMemory> {
641        Ok(self.insert_entry(value)?.into_mut())
642    }
643
644    /// Same as [`std::collections::btree_map::VacantEntry::insert_entry`] but
645    /// returns an error on allocation failure.
646    pub fn insert_entry(mut self, value: V) -> Result<OccupiedEntry<'a, K, V>, OutOfMemory> {
647        let id = self.values.alloc(value)?;
648        match self.cursor.try_insert(self.key, id) {
649            Ok(old) => {
650                debug_assert!(old.is_none());
651                Ok(OccupiedEntry {
652                    cursor: self.cursor,
653                    values: self.values,
654                })
655            }
656            Err(oom) => {
657                self.values.dealloc(id);
658                Err(oom)
659            }
660        }
661    }
662}
663
664impl<K, V> serde::ser::Serialize for TryBTreeMap<K, V>
665where
666    K: Copy + Ord + serde::ser::Serialize,
667    V: serde::ser::Serialize,
668{
669    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
670    where
671        S: serde::Serializer,
672    {
673        use serde::ser::SerializeMap;
674        let mut map = serializer.serialize_map(Some(self.len()))?;
675        for (k, v) in self.iter() {
676            map.serialize_entry(&k, v)?;
677        }
678        map.end()
679    }
680}
681
682impl<'de, K, V> serde::de::Deserialize<'de> for TryBTreeMap<K, V>
683where
684    K: Copy + Ord + serde::de::Deserialize<'de>,
685    V: serde::de::Deserialize<'de>,
686{
687    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
688    where
689        D: serde::Deserializer<'de>,
690    {
691        use core::marker::PhantomData;
692
693        struct Visitor<K: Copy, V>(PhantomData<fn() -> TryBTreeMap<K, V>>);
694
695        impl<'de, K, V> serde::de::Visitor<'de> for Visitor<K, V>
696        where
697            K: Copy + Ord + serde::de::Deserialize<'de>,
698            V: serde::de::Deserialize<'de>,
699        {
700            type Value = TryBTreeMap<K, V>;
701
702            fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
703                f.write_str("a map")
704            }
705
706            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
707            where
708                A: serde::de::MapAccess<'de>,
709            {
710                use serde::de::Error as _;
711                let mut result = TryBTreeMap::new();
712                while let Some((k, v)) = map.next_entry()? {
713                    result.insert(k, v).map_err(|oom| A::Error::custom(oom))?;
714                }
715                Ok(result)
716            }
717        }
718
719        deserializer.deserialize_map(Visitor(PhantomData))
720    }
721}
722
723#[cfg(test)]
724mod tests {
725    use super::*;
726    use crate::error::Result;
727    use alloc::{vec, vec::Vec};
728
729    type M = TryBTreeMap<usize, f32>;
730
731    #[test]
732    fn new() -> Result<()> {
733        let m = M::new();
734        assert!(m.is_empty());
735        Ok(())
736    }
737
738    #[test]
739    fn len() -> Result<()> {
740        let mut m = M::new();
741        for i in 0..10 {
742            assert_eq!(m.len(), i);
743            m.insert(i, i as f32)?;
744        }
745        assert_eq!(m.len(), 10);
746        for i in 0..10 {
747            assert_eq!(m.len(), 10 - i);
748            m.remove(i);
749        }
750        assert_eq!(m.len(), 0);
751        Ok(())
752    }
753
754    #[test]
755    fn is_empty() -> Result<()> {
756        let mut m = M::new();
757        assert!(m.is_empty());
758        m.insert(42, 42.0)?;
759        assert!(!m.is_empty());
760        m.remove(42);
761        assert!(m.is_empty());
762        Ok(())
763    }
764
765    #[test]
766    fn contains_key() -> Result<()> {
767        let mut m = M::new();
768        assert!(!m.contains_key(36));
769        assert!(!m.contains_key(42));
770        m.insert(42, 42.0)?;
771        assert!(!m.contains_key(36));
772        assert!(m.contains_key(42));
773        m.remove(42);
774        assert!(!m.contains_key(36));
775        assert!(!m.contains_key(42));
776        Ok(())
777    }
778
779    #[test]
780    fn get() -> Result<()> {
781        let mut m = M::new();
782        assert!(m.get(36).is_none());
783        assert!(m.get(42).is_none());
784        m.insert(42, 42.0)?;
785        assert!(m.get(36).is_none());
786        assert_eq!(m.get(42), Some(&42.0));
787        m.remove(42);
788        assert!(m.get(36).is_none());
789        assert!(m.get(42).is_none());
790        Ok(())
791    }
792
793    #[test]
794    fn get_mut() -> Result<()> {
795        let mut m = M::new();
796        assert!(m.get_mut(36).is_none());
797        assert!(m.get_mut(42).is_none());
798        m.insert(42, 42.0)?;
799        assert!(m.get_mut(36).is_none());
800        assert_eq!(m.get_mut(42).copied(), Some(42.0));
801        *m.get_mut(42).unwrap() = 99.0;
802        assert_eq!(m.get_mut(42).copied(), Some(99.0));
803        m.remove(42);
804        assert!(m.get_mut(36).is_none());
805        assert!(m.get_mut(42).is_none());
806        Ok(())
807    }
808
809    #[test]
810    fn insert() -> Result<()> {
811        let mut m = M::new();
812        let old = m.insert(11, 0.0)?;
813        assert!(old.is_none());
814        let old = m.insert(11, 1.0)?;
815        assert_eq!(old, Some(0.0));
816        Ok(())
817    }
818
819    #[test]
820    fn remove() -> Result<()> {
821        let mut m = M::new();
822        let old = m.remove(10);
823        assert!(old.is_none());
824        m.insert(10, 123.0)?;
825        let old = m.remove(10);
826        assert_eq!(old, Some(123.0));
827        Ok(())
828    }
829
830    #[test]
831    fn clear() -> Result<()> {
832        let mut m = M::new();
833        for i in 0..10 {
834            m.insert(i, i as f32)?;
835        }
836        m.clear();
837        assert!(m.is_empty());
838        for i in 0..10 {
839            assert!(m.get(i).is_none());
840        }
841        Ok(())
842    }
843
844    #[test]
845    fn iter() -> Result<()> {
846        let mut m = M::new();
847        for i in 0..5 {
848            m.insert(i, i as f32)?;
849        }
850        assert_eq!(
851            m.iter().collect::<Vec<_>>(),
852            vec![(0, &0.0), (1, &1.0), (2, &2.0), (3, &3.0), (4, &4.0)],
853        );
854        Ok(())
855    }
856
857    #[test]
858    fn iter_mut() -> Result<()> {
859        let mut m = M::new();
860        for i in 0..5 {
861            m.insert(i, i as f32)?;
862        }
863        assert_eq!(
864            m.iter_mut()
865                .map(|(k, v)| (k, mem::replace(v, 0.0)))
866                .collect::<Vec<_>>(),
867            vec![(0, 0.0), (1, 1.0), (2, 2.0), (3, 3.0), (4, 4.0)],
868        );
869        for i in 0..5 {
870            assert_eq!(m.get(i), Some(&0.0));
871        }
872        Ok(())
873    }
874
875    #[test]
876    fn keys() -> Result<()> {
877        let mut m = M::new();
878        for i in 0..5 {
879            m.insert(i, i as f32)?;
880        }
881        assert_eq!(m.keys().collect::<Vec<_>>(), vec![0, 1, 2, 3, 4]);
882        Ok(())
883    }
884
885    #[test]
886    fn values() -> Result<()> {
887        let mut m = M::new();
888        for i in 0..5 {
889            m.insert(i, i as f32)?;
890        }
891        assert_eq!(
892            m.values().collect::<Vec<_>>(),
893            vec![&0.0, &1.0, &2.0, &3.0, &4.0],
894        );
895        Ok(())
896    }
897
898    #[test]
899    fn values_mut() -> Result<()> {
900        let mut m = M::new();
901        for i in 0..5 {
902            m.insert(i, i as f32)?;
903        }
904        assert_eq!(
905            m.values_mut()
906                .map(|v| mem::replace(v, 0.0))
907                .collect::<Vec<_>>(),
908            vec![0.0, 1.0, 2.0, 3.0, 4.0],
909        );
910        assert_eq!(
911            m.values().collect::<Vec<_>>(),
912            vec![&0.0, &0.0, &0.0, &0.0, &0.0],
913        );
914        Ok(())
915    }
916
917    #[test]
918    fn range() -> Result<()> {
919        let mut m = M::new();
920        for i in 0..5 {
921            m.insert(i, i as f32)?;
922        }
923        assert_eq!(m.range(..2).collect::<Vec<_>>(), vec![(0, &0.0), (1, &1.0)]);
924        assert_eq!(m.range(3..).collect::<Vec<_>>(), vec![(3, &3.0), (4, &4.0)]);
925        assert_eq!(
926            m.range(1..3).collect::<Vec<_>>(),
927            vec![(1, &1.0), (2, &2.0)],
928        );
929        assert_eq!(
930            m.range(2..=3).collect::<Vec<_>>(),
931            vec![(2, &2.0), (3, &3.0)],
932        );
933        assert_eq!(m.range(5..).collect::<Vec<_>>(), vec![]);
934        assert_eq!(m.range(..0).collect::<Vec<_>>(), vec![]);
935        Ok(())
936    }
937
938    #[test]
939    fn range_mut() -> Result<()> {
940        let mut m = M::new();
941        for i in 0..5 {
942            m.insert(i, i as f32)?;
943        }
944        assert_eq!(
945            m.range_mut(1..3)
946                .map(|(k, v)| (k, mem::replace(v, 99.0)))
947                .collect::<Vec<_>>(),
948            vec![(1, 1.0), (2, 2.0)],
949        );
950        assert_eq!(
951            m.values().copied().collect::<Vec<_>>(),
952            vec![0.0, 99.0, 99.0, 3.0, 4.0]
953        );
954        Ok(())
955    }
956
957    #[test]
958    fn entry() -> Result<()> {
959        let mut m = M::new();
960
961        let v = m.entry(0).or_insert(99.0)?;
962        assert_eq!(*v, 99.0);
963
964        let v = m.entry(0).or_insert(0.0)?;
965        assert_eq!(*v, 99.0);
966
967        let e = match m.entry(1) {
968            Entry::Occupied(_) => unreachable!(),
969            Entry::Vacant(e) => e.insert_entry(42.0)?,
970        };
971        assert_eq!(e.key(), 1);
972        assert_eq!(e.get(), &42.0);
973        let old = e.insert(43.0);
974        assert_eq!(old, 42.0);
975        assert_eq!(m.get(1), Some(&43.0));
976
977        let e = match m.entry(1) {
978            Entry::Occupied(e) => e,
979            Entry::Vacant(_) => unreachable!(),
980        };
981        assert_eq!(e.key(), 1);
982        assert_eq!(e.get(), &43.0);
983        let (k, v) = e.remove_entry();
984        assert_eq!(k, 1);
985        assert_eq!(v, 43.0);
986        assert!(m.get(1).is_none());
987
988        let e = match m.entry(2) {
989            Entry::Occupied(_) => unreachable!(),
990            Entry::Vacant(e) => e,
991        };
992        assert_eq!(e.key(), 2);
993        let v = e.insert(99.0)?;
994        assert_eq!(*v, 99.0);
995
996        Ok(())
997    }
998}