bisetmap/lib.rs
1//! A fast and thread-safe two-way hash map of sets. It is best suited where you need to associate
2//! two collumns uniquely. Each key is associated to one or more other unique values.
3//!
4//! A `BisetMap<L, R>` is a Multi-Hash-Map between values of type `L`, called left values, and values
5//! of type `R`, called right values. This means every left value is associated with one or more
6//! right values and vice versa. Compare this to a [`HashMap`], where every key is associated with
7//! exactly one value.
8//!
9//! The structure is interior mutable and all operations are thread safe. Each clone provides access
10//! to the same underlying data. Serialize and Deserialize from serde are also implemented.
11//!
12//! Internally, a `BisetMap` is composed of two `HashMap`s, one for the left-to-right direction and
13//! one for right-to-left. As such, the big-O performance of the `get`, `remove`, `insert`, and
14//! `contains` methods are the same as those of a `HashMap`.
15//!
16//! As with `HashMap`, it is considered a logic error to modify a value's hash while it is in the
17//! `BisetMap` using a `Cell`, `RefCell`, etc.
18//!
19//! # Examples
20//!
21//! ```
22//! use bisetmap::BisetMap;
23//!
24//! let subscriptions = BisetMap::new();
25//!
26//! // insert client-ids and subscription topics
27//! subscriptions.insert("Bob", "Tech");
28//! subscriptions.insert("Bob", "Math");
29//! subscriptions.insert("Alice", "Tech");
30//! subscriptions.insert("Alice", "Romance");
31//!
32//! // retrieve topic by client-id (left to right)
33//! assert_eq!(subscriptions.get(&"Bob"), ["Math", "Tech"]);
34//! assert_eq!(subscriptions.get(&"Alice"), ["Romance", "Tech"]);
35//!
36//! // retrieve clients by topic (right to left)
37//! assert_eq!(subscriptions.rev_get(&"Tech"), ["Alice", "Bob"]);
38//! assert_eq!(subscriptions.rev_get(&"Math"), ["Bob"]);
39//!
40//! // check membership
41//! assert!(subscriptions.contains(&"Bob", &"Math"));
42//! assert!(!subscriptions.contains(&"Bob", &"Romance"));
43//!
44//! // check key/value existence
45//! assert!(subscriptions.key_exists(&"Alice"));
46//! assert!(subscriptions.value_exists(&"Tech"));
47//! ```
48//!
49//! ## Insertion and Uniqueness
50//!
51//! Consider the following example:
52//!
53//! ```
54//! use bisetmap::BisetMap;
55//!
56//! let bmap = BisetMap::new();
57//! bmap.insert('a', 1);
58//! bmap.insert('a', 1); // what to do here?
59//! ```
60//!
61//! Duplicate key-value pairs are ignored and inserted only once
62//!
63//! [`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
64
65extern crate serde;
66
67use std::collections::{HashMap, HashSet};
68use std::marker::PhantomData;
69use std::sync::{Mutex, Arc};
70use std::hash::Hash;
71use std::fmt;
72
73use serde::de::{Deserialize, Deserializer, Visitor, MapAccess};
74use serde::ser::{Serialize, Serializer, SerializeMap};
75
76
77/// A two-way map between keys (left) and values (right).
78///
79/// See the [module-level documentation] for more details and examples.
80///
81/// [module-level documentation]: index.html
82#[derive(Clone)]
83pub struct BisetMap<L:Eq+Hash+Clone, R:Eq+Hash+Clone> {
84 hh: Arc<Mutex<(HashMap<L, HashSet<R>>, HashMap<R, HashSet<L>>)>>
85}
86
87
88fn insert_item<L:Eq+Hash, R:Eq+Hash>(h: &mut HashMap<L, HashSet<R>>, k: L, v: R) {
89 let s = h.entry(k).or_insert_with(HashSet::new);
90 s.insert(v);
91}
92
93fn remove_item<L:Eq+Hash, R:Eq+Hash>(h: &mut HashMap<L, HashSet<R>>, k: L, v: &R) {
94 if let std::collections::hash_map::Entry::Occupied(mut e) = h.entry(k) {
95 e.get_mut().remove(v);
96 if e.get().is_empty() {
97 e.remove_entry();
98 }
99 }
100}
101
102fn get_item<L:Eq+Hash, R:Eq+Hash+Clone>(h: &HashMap<L, HashSet<R>>, k: &L) -> Vec<R> {
103 match h.get(k) {
104 Some(s) => s.iter().map(Clone::clone).collect(),
105 None => vec![]
106 }
107}
108
109fn remove_items<L:Eq+Hash, R:Eq+Hash+Clone>(h1: &mut HashMap<L, HashSet<R>>, h2: &mut HashMap<R, HashSet<L>>, k: &L) -> Vec<R> {
110 match h1.remove(k) {
111 Some(s) => {
112 let r = s.iter().map(Clone::clone).collect();
113 for v in s {
114 remove_item(h2, v, k)
115 }
116 r
117 },
118 None => vec![]
119 }
120}
121
122impl<L:Eq+Hash+Clone, R:Eq+Hash+Clone> BisetMap<L, R> {
123 /// Creates an empty `BisetMap`.
124 ///
125 /// # Examples
126 ///
127 /// ```
128 /// use bisetmap::BisetMap;
129 ///
130 /// let bmap: BisetMap<char, u32> = BisetMap::new();
131 /// ```
132 pub fn new() -> BisetMap<L, R> {
133 BisetMap::default()
134 }
135
136 /// Creates an empty `BisetMap` with the given capacity.
137 ///
138 /// # Examples
139 ///
140 /// ```
141 /// use bisetmap::BisetMap;
142 ///
143 /// let bmap: BisetMap<char, u32> = BisetMap::with_capacity(5);
144 /// ```
145 pub fn with_capacity(capacity: usize) -> BisetMap<L, R> {
146 BisetMap {
147 hh: Arc::new(Mutex::new( (HashMap::with_capacity(capacity), HashMap::with_capacity(capacity)) ))
148 }
149 }
150
151 /// Removes all key-value pairs from the `BisetMap`, but keeps the allocated memory for reuse.
152 ///
153 /// # Examples
154 ///
155 /// ```
156 /// use bisetmap::BisetMap;
157 ///
158 /// let bmap = BisetMap::new();
159 /// bmap.insert('a', 1);
160 /// bmap.insert('b', 2);
161 /// bmap.insert('c', 3);
162 /// bmap.clear();
163 /// assert!(bmap.len() == 0);
164 /// ```
165 pub fn clear(&self) {
166 let (ref mut h1, ref mut h2) = *self.hh.lock().unwrap();
167 h1.clear();
168 h2.clear();
169 }
170
171 /// Returns a new BisetMap where keys and values are swapped.
172 ///
173 /// # Examples
174 ///
175 /// ```
176 /// use bisetmap::BisetMap;
177 ///
178 /// let bmap = BisetMap::new();
179 /// bmap.insert('a', 1);
180 /// bmap.insert('b', 2);
181 /// bmap.insert('c', 3);
182 /// let rmap = bmap.rev();
183 /// assert_eq!(rmap.get(&1), ['a']);
184 /// ```
185 pub fn rev(&self) -> BisetMap<R, L> {
186 let (ref h1, ref h2) = *self.hh.lock().unwrap();
187 BisetMap {
188 hh: Arc::new(Mutex::new( (h2.clone(), h1.clone()) ))
189 }
190 }
191
192 /// Returns a vector of (key,values) pairs, where values itself is a vector.
193 /// (Order of all pairs is unknown)
194 ///
195 /// # Examples
196 ///
197 /// ```
198 /// use bisetmap::BisetMap;
199 ///
200 /// let bmap = BisetMap::new();
201 /// bmap.insert('a', 1);
202 /// bmap.insert('a', 2);
203 /// bmap.insert('b', 3);
204 /// assert_eq!(bmap.collect(), vec![('a',vec![1,2]), ('b',vec![3])]);
205 /// ```
206 pub fn collect(&self) -> Vec<(L, Vec<R>)> {
207 self.hh.lock().unwrap().0
208 .iter()
209 .map(|(l, r)| (l.clone(), r.iter().map(Clone::clone).collect()))
210 .collect()
211 }
212
213 /// Returns a vector of (key,value) pairs.
214 /// (Order of pairs is unknown)
215 ///
216 /// # Examples
217 ///
218 /// ```
219 /// use bisetmap::BisetMap;
220 ///
221 /// let bmap = BisetMap::new();
222 /// bmap.insert('a', 1);
223 /// bmap.insert('a', 2);
224 /// bmap.insert('b', 3);
225 /// assert_eq!(bmap.flat_collect(), [('a',1), ('a',2), ('b',3)]);
226 /// ```
227 pub fn flat_collect(&self) -> Vec<(L, R)> {
228 self.hh.lock().unwrap().0
229 .iter()
230 .flat_map(|(l, rs)| rs.iter().map(move |r| (l.clone(), r.clone())))
231 .collect()
232 }
233
234 /// Inserts the given key-value pair into the `BisetMap`.
235 ///
236 /// # Examples
237 ///
238 /// ```
239 /// use bisetmap::BisetMap;
240 ///
241 /// let bmap = BisetMap::new();
242 /// bmap.insert('a', 1);
243 /// bmap.insert('a', 1);
244 /// bmap.insert('a', 2);
245 /// bmap.insert('b', 3);
246 /// assert_eq!(bmap.flat_collect(), [('a',1), ('a',2), ('b',3)]);
247 /// ```
248 pub fn insert(&self, k: L, v: R) {
249 let (ref mut h1, ref mut h2) = *self.hh.lock().unwrap();
250 insert_item(h1, k.clone(), v.clone());
251 insert_item(h2, v, k);
252 }
253
254 /// Removes the specified key-value pair from the `BisetMap`.
255 ///
256 /// # Examples
257 ///
258 /// ```
259 /// use bisetmap::BisetMap;
260 ///
261 /// let bmap = BisetMap::new();
262 /// bmap.insert('a', 1);
263 /// bmap.insert('a', 1);
264 /// bmap.insert('a', 2);
265 /// bmap.insert('c', 3);
266 /// assert_eq!(bmap.len(), 2);
267 /// assert_eq!(bmap.rev_len(), 3);
268 /// bmap.remove(&'a', &2);
269 /// assert_eq!(bmap.len(), 2);
270 /// assert_eq!(bmap.rev_len(), 2);
271 /// ```
272 pub fn remove(&self, k: &L, v: &R) {
273 let (ref mut h1, ref mut h2) = *self.hh.lock().unwrap();
274 remove_item(h1, k.clone(), &v.clone());
275 remove_item(h2, v.clone(), &k.clone());
276 }
277
278 /// Returns `true` if the map contains the given key-value pair and `false` otherwise.
279 ///
280 /// # Examples
281 ///
282 /// ```
283 /// use bisetmap::BisetMap;
284 ///
285 /// let bmap = BisetMap::new();
286 /// bmap.insert('a', 1);
287 /// assert!(bmap.contains(&'a', &1));
288 /// assert!(!bmap.contains(&'b', &1));
289 /// assert!(!bmap.contains(&'a', &2));
290 /// ```
291 pub fn contains(&self, k: &L, v: &R) -> bool {
292 match self.hh.lock().unwrap().0.get(k) {
293 Some(s) => s.contains(v),
294 None => false
295 }
296 }
297
298 /// Returns `true` if the map contains the given key (left) value and `false` otherwise.
299 ///
300 /// # Examples
301 ///
302 /// ```
303 /// use bisetmap::BisetMap;
304 ///
305 /// let bmap = BisetMap::new();
306 /// bmap.insert('a', 1);
307 /// assert!(bmap.key_exists(&'a'));
308 /// assert!(!bmap.key_exists(&'b'));
309 /// ```
310 pub fn key_exists(&self, k: &L) -> bool {
311 self.hh.lock().unwrap().0.contains_key(k)
312 }
313
314 /// Returns `true` if the map contains the given value (right) and `false` otherwise.
315 ///
316 /// # Examples
317 ///
318 /// ```
319 /// use bisetmap::BisetMap;
320 ///
321 /// let bmap = BisetMap::new();
322 /// bmap.insert('a', 1);
323 /// assert!(bmap.value_exists(&1));
324 /// assert!(!bmap.value_exists(&2));
325 /// ```
326 pub fn value_exists(&self, v: &R) -> bool {
327 self.hh.lock().unwrap().1.contains_key(v)
328 }
329
330 /// Returns a vector of values (right) corresponding to the given key (left).
331 ///
332 /// # Examples
333 ///
334 /// ```
335 /// use bisetmap::BisetMap;
336 ///
337 /// let bmap = BisetMap::new();
338 /// bmap.insert('a', 1);
339 /// assert_eq!(bmap.get(&'a'), [1]);
340 /// assert_eq!(bmap.get(&'z'), []);
341 /// ```
342 pub fn get(&self, k: &L) -> Vec<R> {
343 get_item(&self.hh.lock().unwrap().0, &k)
344 }
345
346 /// Returns a vector of keys (left) corresponding to the given value (right).
347 ///
348 /// # Examples
349 ///
350 /// ```
351 /// use bisetmap::BisetMap;
352 ///
353 /// let bmap = BisetMap::new();
354 /// bmap.insert('a', 1);
355 /// assert_eq!(bmap.rev_get(&1), ['a']);
356 /// assert_eq!(bmap.rev_get(&2), []);
357 /// ```
358 pub fn rev_get(&self, v: &R) -> Vec<L> {
359 get_item(&self.hh.lock().unwrap().1, &v)
360 }
361
362 /// Removes the specified key and all values associated with it.
363 ///
364 /// Returns a vector of previous values associated with given key.
365 ///
366 /// # Examples
367 ///
368 /// ```
369 /// use bisetmap::BisetMap;
370 ///
371 /// let bmap = BisetMap::new();
372 /// bmap.insert('a', 1);
373 /// bmap.insert('a', 2);
374 /// bmap.insert('c', 3);
375 /// assert_eq!(bmap.delete(&'a'), [1, 2]);
376 /// assert_eq!(bmap.len(), 1);
377 /// ```
378 pub fn delete(&self, k: &L) -> Vec<R> {
379 let (ref mut h1, ref mut h2) = *self.hh.lock().unwrap();
380 remove_items(h1, h2, &k)
381 }
382
383 /// Removes the specified value and all keys associated with it.
384 ///
385 /// Returns a vector of previous keys associated with given value.
386 ///
387 /// # Examples
388 ///
389 /// ```
390 /// use bisetmap::BisetMap;
391 ///
392 /// let bmap = BisetMap::new();
393 /// bmap.insert('a', 1);
394 /// bmap.insert('b', 1);
395 /// bmap.insert('c', 2);
396 /// assert_eq!(bmap.rev_delete(&1), ['a', 'b']);
397 /// assert_eq!(bmap.len(), 1);
398 /// ```
399 pub fn rev_delete(&self, v: &R) -> Vec<L> {
400 let (ref mut h1, ref mut h2) = *self.hh.lock().unwrap();
401 remove_items(h2, h1, &v)
402 }
403
404 /// Returns the number of unique keys (left).
405 ///
406 /// # Examples
407 ///
408 /// ```
409 /// use bisetmap::BisetMap;
410 ///
411 /// let bmap = BisetMap::new();
412 /// bmap.insert('a', 1);
413 /// bmap.insert('b', 2);
414 /// bmap.insert('c', 3);
415 /// bmap.insert('c', 4);
416 /// assert_eq!(bmap.len(), 3);
417 /// ```
418 pub fn len(&self) -> usize {
419 self.hh.lock().unwrap().0.len()
420 }
421
422 /// Returns the number of unique values (right).
423 ///
424 /// # Examples
425 ///
426 /// ```
427 /// use bisetmap::BisetMap;
428 ///
429 /// let bmap = BisetMap::new();
430 /// bmap.insert('a', 1);
431 /// bmap.insert('b', 2);
432 /// bmap.insert('c', 3);
433 /// bmap.insert('d', 3);
434 /// assert_eq!(bmap.rev_len(), 3);
435 /// ```
436 pub fn rev_len(&self) -> usize {
437 self.hh.lock().unwrap().1.len()
438 }
439
440 /// Returns `true` if the map contains no key-value pairs, and `false` otherwise.
441 ///
442 /// # Examples
443 ///
444 /// ```
445 /// use bisetmap::BisetMap;
446 ///
447 /// let bmap = BisetMap::new();
448 /// assert!(bmap.is_empty());
449 /// bmap.insert('a', 1);
450 /// assert!(!bmap.is_empty());
451 /// bmap.rev_delete(&1);
452 /// assert!(bmap.is_empty());
453 /// ```
454 pub fn is_empty(&self) -> bool {
455 self.hh.lock().unwrap().0.is_empty()
456 }
457}
458
459
460impl<L: Eq+Hash+Clone, R: Eq+Hash+Clone> Default for BisetMap<L,R> {
461 fn default() -> BisetMap<L, R> {
462 BisetMap {
463 hh: Arc::new(Mutex::new( (HashMap::default(), HashMap::default()) ))
464 }
465 }
466}
467
468impl<L: Eq+Hash+Clone+fmt::Debug, R: Eq+Hash+Clone+fmt::Debug> fmt::Debug for BisetMap<L, R> {
469 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
470 write!(f, "{{")?;
471 for (i, (left, right)) in self.hh.lock().unwrap().0.iter().enumerate() {
472 let comma = if i == 0 { "" } else { ", " };
473 write!(f, "{}{:?} => {:?}", comma, left, right)?;
474 }
475 write!(f, "}}")?;
476 Ok(())
477 }
478}
479
480
481
482
483
484impl<L:Eq+Hash+Clone+Serialize, R:Eq+Hash+Clone+Serialize> Serialize for BisetMap<L, R> {
485 fn serialize<S:Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
486 let data = self.collect();
487 let mut map = serializer.serialize_map(Some(data.len()))?;
488 for (k, v) in data {
489 map.serialize_entry(&k, &v)?;
490 }
491 map.end()
492 }
493}
494
495
496struct BisetMapVisitor<L:Eq+Hash+Clone, R:Eq+Hash+Clone> {
497 marker: PhantomData<fn() -> BisetMap<L, R>>
498}
499
500impl<L:Eq+Hash+Clone, R:Eq+Hash+Clone> BisetMapVisitor<L, R> {
501 fn new() -> Self {
502 BisetMapVisitor {
503 marker: PhantomData
504 }
505 }
506}
507
508impl<'de, L:Eq+Hash+Clone+Deserialize<'de>, R:Eq+Hash+Clone+Deserialize<'de>> Visitor<'de> for BisetMapVisitor<L, R> {
509 type Value = BisetMap<L, R>;
510
511 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
512 formatter.write_str("a biset map")
513 }
514
515 fn visit_map<M: MapAccess<'de>>(self, mut access: M) -> Result<Self::Value, M::Error> {
516 let bmap = BisetMap::with_capacity(access.size_hint().unwrap_or(0));
517 while let Some((key, values)) = access.next_entry::<L, Vec<R>>()? {
518 for value in values {
519 bmap.insert(key.clone(), value);
520 }
521 }
522 Ok(bmap)
523 }
524}
525
526impl<'de, L:Eq+Hash+Clone+Deserialize<'de>, R:Eq+Hash+Clone+Deserialize<'de>> Deserialize<'de> for BisetMap<L, R> {
527 fn deserialize<D:Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
528 deserializer.deserialize_map(BisetMapVisitor::new())
529 }
530}
531
532
533
534
535
536
537#[cfg(test)]
538mod tests {
539 use BisetMap;
540
541 #[test]
542 fn test1() {
543 let h = BisetMap::new();
544 h.insert("sdf", "sdfsd");
545 h.insert("sdf", "sdfsd");
546 h.insert("a", "1");
547 h.insert("b", "1");
548 h.insert("c", "2");
549 h.insert("c", "3");
550 h.insert("c", "4");
551
552 println!("{:?}", h);
553 println!("{:?}", h.rev());
554 println!("{:?}", h.collect());
555 }
556
557 #[test]
558 fn clone_works_with_same_internal_memory() {
559 let h1 = BisetMap::new();
560 let h2 = h1.clone();
561 h1.insert("hello", "world");
562 assert_eq!(h2.get(&"hello"), ["world"]);
563 }
564
565 #[test]
566 fn test_len_function() {
567 let h = BisetMap::new();
568 assert_eq!(h.len(), 0);
569 assert_eq!(h.rev_len(),0);
570
571 h.insert("a", "1");
572 h.insert("b", "1");
573 h.insert("c", "2");
574 assert_eq!(h.len(), 3);
575 assert_eq!(h.rev_len(),2);
576
577 h.rev_delete(&"1");
578 assert_eq!(h.len(), 1);
579 assert_eq!(h.rev_len(),1);
580 }
581
582 #[test]
583 fn is_empty_after_removal() {
584 let h = BisetMap::new();
585 assert!(h.is_empty());
586
587 h.insert("a", "1");
588 h.insert("b", "1");
589 h.insert("c", "2");
590 assert!(!h.is_empty());
591
592 h.rev_delete(&"1");
593 h.delete(&"c");
594 assert!(h.is_empty());
595 }
596}