veloren_world/util/
map_vec.rs

1use crate::util::DHashMap;
2use std::hash::Hash;
3
4/** A static table of known values where any key always maps to a single value.
5
6It's not really intended to be a "collection" in the same way that, say, HashMap or Vec is
7Since it's not intended to have a way of expressing that a value is not present (hence the default behaviour)
8It's really quite specifically tailored to its application in the economy code where it wouldn't make sense to not have certain entries
9Store is a bit different in that it is the one to generate an index, and so it can hold as many things as you like
10Whereas with MapVec, we always know the index ahead of time.
11**/
12
13#[derive(Clone, Debug)]
14pub struct MapVec<K, T> {
15    /// We use this hasher (FxHasher32) because
16    /// (1) we don't care about DDOS attacks (ruling out SipHash);
17    /// (2) we care about determinism across computers (ruling out AAHash);
18    /// (3) we have 1-byte keys (for which FxHash is supposedly fastest).
19    entries: DHashMap<K, T>,
20    default: T,
21}
22
23/// Need manual implementation of Default since K doesn't need that bound.
24impl<K, T: Default> Default for MapVec<K, T> {
25    fn default() -> Self {
26        Self {
27            entries: Default::default(),
28            default: Default::default(),
29        }
30    }
31}
32
33impl<K: Copy + Eq + Hash, T: Clone> MapVec<K, T> {
34    pub fn from_list<'a>(i: impl IntoIterator<Item = &'a (K, T)>, default: T) -> Self
35    where
36        K: 'a,
37        T: 'a,
38    {
39        Self {
40            entries: i.into_iter().cloned().collect(),
41            default,
42        }
43    }
44
45    pub fn from_iter(i: impl Iterator<Item = (K, T)>, default: T) -> Self {
46        Self {
47            entries: i.collect(),
48            default,
49        }
50    }
51
52    pub fn from_default(default: T) -> Self {
53        Self {
54            entries: DHashMap::default(),
55            default,
56        }
57    }
58
59    pub fn get_mut(&mut self, entry: K) -> &mut T {
60        let default = &self.default;
61        self.entries.entry(entry).or_insert_with(|| default.clone())
62    }
63
64    pub fn get(&self, entry: K) -> &T { self.entries.get(&entry).unwrap_or(&self.default) }
65
66    pub fn map<U: Default>(self, mut f: impl FnMut(K, T) -> U) -> MapVec<K, U> {
67        MapVec {
68            entries: self
69                .entries
70                .into_iter()
71                .map(|(s, v)| (s, f(s, v)))
72                .collect(),
73            default: U::default(),
74        }
75    }
76
77    pub fn iter(&self) -> impl Iterator<Item = (K, &T)> + '_ {
78        self.entries.iter().map(|(s, v)| (*s, v))
79    }
80
81    pub fn iter_mut(&mut self) -> impl Iterator<Item = (K, &mut T)> + '_ {
82        self.entries.iter_mut().map(|(s, v)| (*s, v))
83    }
84}
85
86impl<K: Copy + Eq + Hash, T: Clone> std::ops::Index<K> for MapVec<K, T> {
87    type Output = T;
88
89    fn index(&self, entry: K) -> &Self::Output { self.get(entry) }
90}
91
92impl<K: Copy + Eq + Hash, T: Clone> std::ops::IndexMut<K> for MapVec<K, T> {
93    fn index_mut(&mut self, entry: K) -> &mut Self::Output { self.get_mut(entry) }
94}