1
0

multi_map.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. use std::borrow::Borrow;
  2. use std::collections::HashMap;
  3. use std::hash::{Hash, Hasher};
  4. struct RawItem<K1, K2, V>(*mut (K1, K2, V));
  5. unsafe impl<K1, K2, V> Send for RawItem<K1, K2, V> {}
  6. unsafe impl<K1, K2, V> Sync for RawItem<K1, K2, V> {}
  7. /// MultiMap is a hash map that can index an item by two keys
  8. /// For example, after an item with key (a, b) is insert, `map.get1(a)` and
  9. /// `map.get2(b)` both returns the item. Likewise the `remove1` and `remove2`.
  10. pub struct MultiMap<K1, K2, V> {
  11. map1: HashMap<Key<K1>, RawItem<K1, K2, V>>,
  12. map2: HashMap<Key<K2>, RawItem<K1, K2, V>>,
  13. }
  14. struct Key<T>(*const T);
  15. unsafe impl<T> Send for Key<T> {}
  16. unsafe impl<T> Sync for Key<T> {}
  17. impl<T> Borrow<T> for Key<T> {
  18. fn borrow(&self) -> &T {
  19. unsafe { &*self.0 }
  20. }
  21. }
  22. impl<T: Hash> Hash for Key<T> {
  23. fn hash<H: Hasher>(&self, state: &mut H) {
  24. (self.borrow() as &T).hash(state)
  25. }
  26. }
  27. impl<T: PartialEq> PartialEq for Key<T> {
  28. fn eq(&self, other: &Self) -> bool {
  29. (self.borrow() as &T).eq(other.borrow())
  30. }
  31. }
  32. impl<T: Eq> Eq for Key<T> {}
  33. impl<K1, K2, V> MultiMap<K1, K2, V> {
  34. pub fn new() -> Self {
  35. MultiMap {
  36. map1: HashMap::new(),
  37. map2: HashMap::new(),
  38. }
  39. }
  40. }
  41. #[allow(dead_code)]
  42. impl<K1, K2, V> MultiMap<K1, K2, V>
  43. where
  44. K1: Hash + Eq + Send,
  45. K2: Hash + Eq + Send,
  46. V: Send,
  47. {
  48. pub fn insert(&mut self, k1: K1, k2: K2, v: V) -> Result<(), (K1, K2, V)> {
  49. if self.map1.contains_key(&k1) || self.map2.contains_key(&k2) {
  50. return Err((k1, k2, v));
  51. }
  52. let item = Box::new((k1, k2, v));
  53. let k1 = Key(&item.0);
  54. let k2 = Key(&item.1);
  55. let item = Box::into_raw(item);
  56. self.map1.insert(k1, RawItem(item));
  57. self.map2.insert(k2, RawItem(item));
  58. Ok(())
  59. }
  60. pub fn get1(&self, k1: &K1) -> Option<&V> {
  61. let item = self.map1.get(k1)?;
  62. let item = unsafe { &*item.0 };
  63. Some(&item.2)
  64. }
  65. pub fn get1_mut(&mut self, k1: &K1) -> Option<&mut V> {
  66. let item = self.map1.get(k1)?;
  67. let item = unsafe { &mut *item.0 };
  68. Some(&mut item.2)
  69. }
  70. pub fn get2(&self, k2: &K2) -> Option<&V> {
  71. let item = self.map2.get(k2)?;
  72. let item = unsafe { &*item.0 };
  73. Some(&item.2)
  74. }
  75. pub fn get_mut2(&mut self, k2: &K2) -> Option<&mut V> {
  76. let item = self.map2.get(k2)?;
  77. let item = unsafe { &mut *item.0 };
  78. Some(&mut item.2)
  79. }
  80. pub fn remove1(&mut self, k1: &K1) -> Option<V> {
  81. let item = self.map1.remove(k1)?;
  82. let item = unsafe { Box::from_raw(item.0) };
  83. self.map2.remove(&item.1);
  84. Some(item.2)
  85. }
  86. pub fn remove2(&mut self, k2: &K2) -> Option<V> {
  87. let item = self.map2.remove(k2)?;
  88. let item = unsafe { Box::from_raw(item.0) };
  89. self.map1.remove(&item.0);
  90. Some(item.2)
  91. }
  92. }
  93. impl<K1, K2, V> Drop for MultiMap<K1, K2, V> {
  94. fn drop(&mut self) {
  95. self.map1.clear();
  96. self.map2
  97. .drain()
  98. .for_each(|(_, item)| drop(unsafe { Box::from_raw(item.0) }));
  99. }
  100. }