1use std::collections::{HashMap, HashSet};
2use std::fmt::Debug;
3use std::hash::Hash;
4
5pub struct MbiMap<K: Hash, V: Hash> {
6 kvs: HashMap<K, HashSet<V>>,
7 vks: HashMap<V, HashSet<K>>,
8 empty_k: HashSet<V>,
9 empty_v: HashSet<K>,
10}
11
12impl<K: Debug + Hash, V: Debug + Hash> Debug for MbiMap<K, V> {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 self.kvs.fmt(f)
15 }
16}
17
18impl<K: Clone + Eq + Hash, V: Clone + Eq + Hash> MbiMap<K, V> {
19 pub fn new() -> Self {
20 Self {
21 kvs: HashMap::new(),
22 vks: HashMap::new(),
23 empty_k: HashSet::new(),
24 empty_v: HashSet::new(),
25 }
26 }
27
28 pub fn insert(&mut self, k: K, v: V) {
29 let (k1, v1) = (k.clone(), v.clone());
30 self.kvs.entry(k1).or_insert_with(HashSet::new).insert(v1);
31 self.vks.entry(v).or_insert_with(HashSet::new).insert(k);
32 }
33
34 pub fn insert_by_left(&mut self, k: K, vs: Vec<V>) {
35 let (k1, vs1) = (k.clone(), vs.clone());
36 self.kvs.entry(k1).or_insert_with(HashSet::new).extend(vs1);
37 for v in vs {
38 self.vks
39 .entry(v)
40 .or_insert_with(HashSet::new)
41 .insert(k.clone());
42 }
43 }
44
45 pub fn insert_by_right(&mut self, ks: Vec<K>, v: V) {
46 let (ks1, v1) = (ks.clone(), v.clone());
47 self.vks.entry(v1).or_insert_with(HashSet::new).extend(ks1);
48 for k in ks {
49 self.kvs
50 .entry(k)
51 .or_insert_with(HashSet::new)
52 .insert(v.clone());
53 }
54 }
55
56 pub fn get_by_left(&self, k: &K) -> &HashSet<V> {
57 self.kvs.get(k).unwrap_or(&self.empty_k)
58 }
59
60 pub fn get_by_right(&self, v: &V) -> &HashSet<K> {
61 self.vks.get(v).unwrap_or(&self.empty_v)
62 }
63
64 pub fn remove(&mut self, k: &K, v: &V) {
65 if let Some(kk) = self.kvs.get_mut(k) {
66 kk.remove(v);
67 }
68 if let Some(vv) = self.vks.get_mut(v) {
69 vv.remove(k);
70 }
71 }
72
73 pub fn remove_by_left(&mut self, k: &K, vs: &Vec<V>) {
74 for v in vs {
75 self.remove(k, v);
76 }
77 }
78
79 pub fn remove_by_right(&mut self, ks: &Vec<K>, v: &V) {
80 for k in ks {
81 self.remove(k, v);
82 }
83 }
84
85 pub fn remove_all_by_left(&mut self, k: &K) -> Option<HashSet<V>> {
86 let oitems = self.kvs.remove(k);
87 if let Some(vs) = &oitems {
88 for v in vs {
89 if let Some(vv) = self.vks.get_mut(v) {
90 vv.remove(k);
91 }
92 }
93 }
94 oitems
95 }
96
97 pub fn remove_all_by_right(&mut self, v: &V) -> Option<HashSet<K>> {
98 let oitems = self.vks.remove(v);
99 if let Some(ks) = &oitems {
100 for k in ks {
101 if let Some(kk) = self.kvs.get_mut(k) {
102 kk.remove(v);
103 }
104 }
105 }
106 oitems
107 }
108
109 pub fn clear(&mut self) {
110 self.kvs.clear();
111 self.vks.clear();
112 }
113}