1use std::collections::{BTreeMap, HashSet};
2use std::hash::Hash;
3use std::ops::Deref;
4
5#[derive(Debug, Default)]
6pub struct MultiMap<K, V>
7where
8 K: Ord + Eq + Hash,
9 V: Eq + Hash,
10{
11 backing: BTreeMap<K, HashSet<V>>,
12}
13
14impl<K, V> MultiMap<K, V>
15where
16 K: Ord + Eq + Hash,
17 V: Eq + Hash,
18{
19 pub fn insert(&mut self, key: K, value: V) -> bool {
21 self.backing
22 .entry(key)
23 .or_insert_with(Default::default)
24 .insert(value)
25 }
26
27 pub fn remove(&mut self, key: &K, value: &V) -> bool {
30 if let Some(values) = self.backing.get_mut(key) {
31 let only_one_left = values.len() == 1;
32 if !only_one_left {
33 return values.remove(value);
35 }
36 if value
37 != values
38 .iter()
39 .next()
40 .expect("We know there is only one element in collection, tested above; qed")
41 {
42 return false;
44 }
45 } else {
46 return false;
48 }
49 self.backing.remove(key).is_some()
51 }
52}
53
54impl<K, V> Deref for MultiMap<K, V>
55where
56 K: Ord + Eq + Hash,
57 V: Eq + Hash,
58{
59 type Target = BTreeMap<K, HashSet<V>>;
60
61 fn deref(&self) -> &Self::Target {
62 &self.backing
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn insert_and_get() {
72 let mut map: MultiMap<u8, u32> = MultiMap::default();
73 map.insert(1u8, 3u32);
74 map.insert(2u8, 6u32);
75 map.insert(1u8, 9u32);
76 let set: HashSet<u32> = [3u32, 9u32].iter().cloned().collect();
77 assert_eq!(map.get(&1u8).unwrap(), &set);
78 }
79}