total_order_multi_map/
entry.rs

1use std::hash::Hash;
2use std::cmp::Eq;
3use std::fmt::{self, Debug};
4use std::collections::hash_map;
5use std::ops::DerefMut;
6use std::mem;
7
8use stable_deref_trait::StableDeref;
9use vec_drain_where::*;
10
11use utils::DebugIterableOpaque;
12
13use super::{TotalOrderMultiMap, EntryValues, EntryValuesMut};
14
15impl<K, V> TotalOrderMultiMap<K, V>
16    where K: Hash + Eq + Copy,
17          V: StableDeref + DerefMut
18{
19    /// return a entry for a given key
20    pub fn entry(&mut self, key: K) -> Entry<K, V> {
21        let vec_data_ref = &mut self.vec_data;
22        let map_access_entry = self.map_access.entry(key);
23        Entry { vec_data_ref, map_access_entry }
24    }
25}
26
27pub struct Entry<'a, K, V>
28    where K: 'a,
29          V: StableDeref + DerefMut + 'a,
30{
31    vec_data_ref: &'a mut Vec<(K, V)>,
32    map_access_entry: hash_map::Entry<'a, K, Vec<*mut V::Target>>
33}
34
35impl<'a, K, V> Debug for Entry<'a, K, V>
36    where K: Hash + Eq + Copy + Debug + 'a,
37          V: StableDeref + DerefMut + 'a,
38          V::Target: Debug
39{
40    fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
41        use self::hash_map::Entry::*;
42        let dio: Box<Debug> = match self.map_access_entry {
43            Occupied(ref o) => {
44                Box::new(DebugIterableOpaque::new(o.get().iter().map(|&ptr| unsafe { &*ptr })))
45            },
46            //SAFE because of TotalOrderMultiMap safty constraints the pointer is always valid
47            Vacant(..) => Box::new("[]")
48        } ;
49        fter.debug_struct("Entry")
50            .field("key", &self.key())
51            .field("values", &*dio)
52            .finish()
53    }
54}
55
56
57
58impl<'a, K, V> Entry<'a, K, V>
59    where K: Hash + Eq + Copy + 'a,
60          V: StableDeref + DerefMut + 'a
61{
62    /// access the key used to construct this entry
63    pub fn key(&self) -> K {
64        *self.map_access_entry.key()
65    }
66
67    /// return how many values are associated with this entries key
68    pub fn value_count(&self) -> usize {
69        self.values().len()
70    }
71
72    /// Iterate over all values already inserted for the key.
73    pub fn values(&self) -> EntryValues<V::Target> {
74        use self::hash_map::Entry::*;
75        match self.map_access_entry {
76            Occupied(ref o) => EntryValues::new(o.get().iter()),
77            Vacant(..) => EntryValues::empty()
78        }
79    }
80
81    /// Iterate over mutable references of values already inserted for the key.
82    pub fn values_mut(&mut self) -> EntryValuesMut<V::Target> {
83        use self::hash_map::Entry::*;
84        match self.map_access_entry {
85            Occupied(ref mut o) => EntryValuesMut::new(o.get_mut().iter_mut()),
86            Vacant(..) => EntryValuesMut::empty()
87        }
88    }
89
90    /// Add a value to the values associated with the given keys.
91    pub fn add(self, val: V) -> EntryValuesMut<'a, V::Target> {
92        use self::hash_map::Entry::*;
93        let mut val = val;
94
95        let Entry { vec_data_ref, map_access_entry } = self;
96        let ptr: *mut V::Target = val.deref_mut();
97        let key = *map_access_entry.key();
98
99        vec_data_ref.push((key, val));
100
101        let vals = match map_access_entry {
102            Occupied(mut oe) => {
103                let mut mut_vec = oe.into_mut();
104                mut_vec.push(ptr);
105                mut_vec
106            },
107            Vacant(ve) => {
108                ve.insert(vec![ptr])
109
110            }
111        };
112
113        // Can't use the entries return value as it's &mut Vec<ptr> with last == ptr.
114        EntryValuesMut::new(vals.iter_mut())
115    }
116
117    /// Sets a value for a given key, removing all previous associated values.
118    ///
119    /// Returns the values previous associated with the key.
120    pub fn set(self, val: V) -> Vec<V> {
121        use self::hash_map::Entry::*;
122        let mut val = val;
123
124        let Entry { vec_data_ref, map_access_entry } = self;
125        let ptr: *mut V::Target = val.deref_mut();
126        let key = *map_access_entry.key();
127
128        // we can't replace as we need to keep the insertion order
129        vec_data_ref.push((key, val));
130
131        let mut nr_of_old_vals =
132            match map_access_entry {
133                Occupied(mut oe) => {
134                    mem::replace(oe.get_mut(), vec![ptr]).len()
135                },
136                Vacant(ve) => {
137                    ve.insert(vec![ptr]);
138                    0
139                }
140            };
141
142        vec_data_ref.e_drain_where(move |&mut (ref k, _)| {
143            if nr_of_old_vals > 0 && k == &key {
144                nr_of_old_vals -= 1;
145                true
146            } else {
147                false
148            }
149        }).map(|(_k,v)| v).collect()
150    }
151}
152
153
154
155#[cfg(test)]
156mod test {
157    use super::*;
158
159    #[test]
160    fn iter_entry_values() {
161        let mut map = TotalOrderMultiMap::new();
162        map.add("k1", "v1".to_owned());
163        map.add("k2", "v2".to_owned());
164        map.add("k1", "v3".to_owned());
165        map.add("k3", "v4".to_owned());
166
167        assert_eq!(
168            vec!["v1", "v3"],
169            map.entry("k1").values().collect::<Vec<_>>()
170        );
171    }
172
173    #[test]
174    fn entry_set_with_prev_vals() {
175        let mut map = TotalOrderMultiMap::new();
176        map.add("k1", "v1".to_owned());
177        map.add("k2", "v2".to_owned());
178        map.add("k1", "v3".to_owned());
179        map.add("k3", "v4".to_owned());
180
181        let res = map.entry("k1").set("xx".to_owned());
182        assert_eq!(vec!["v1".to_owned(), "v3".to_owned()], res);
183
184        assert_eq!(
185            vec![ ("k2", "v2"), ("k3", "v4"), ("k1" , "xx") ],
186            map.iter().collect::<Vec<_>>()
187        );
188    }
189
190    #[test]
191    fn entry_set_with_no_prev_vals() {
192        let mut map = TotalOrderMultiMap::new();
193        map.entry("k1").set("xx".to_owned());
194        assert_eq!(
195            vec![ ("k1" , "xx") ],
196            map.iter().collect::<Vec<_>>()
197        );
198    }
199
200    #[test]
201    fn base() {
202        let mut map = TotalOrderMultiMap::new();
203        map.add("k1", "v1".to_owned());
204        map.add("k2", "b".to_owned());
205        map.add("k1", "v2".to_owned());
206
207
208        {
209            let entry = map.entry("k1");
210            assert_eq!("k1", entry.key());
211            assert_eq!(2, entry.value_count());
212            entry.add("vX".to_owned());
213        }
214
215        assert_eq!(
216            ["v1", "b", "v2", "vX"],
217            map.values().collect::<Vec<_>>().as_slice()
218        );
219
220        assert_eq!(
221            ["v1", "v2", "vX"],
222            map.get("k1").collect::<Vec<_>>().as_slice()
223        );
224
225        {
226            let entry = map.entry("k99");
227            assert_eq!("k99", entry.key());
228            assert_eq!(0, entry.value_count());
229        }
230
231        {
232            let entry = map.entry("k88");
233            assert_eq!("k88", entry.key());
234            assert_eq!(0, entry.value_count());
235            entry.add("end.".to_owned());
236        }
237
238        assert_eq!(
239            [("k1", "v1"), ("k2", "b"), ("k1", "v2"), ("k1", "vX"), ("k88", "end.")],
240            map.iter().collect::<Vec<_>>().as_slice()
241        );
242
243
244    }
245}
246
247