1 use crate::t::Map; 2 use crate::{DashMap, HashMap}; 3 use core::borrow::Borrow; 4 use core::fmt; 5 use core::hash::{BuildHasher, Hash}; 6 use std::collections::hash_map::RandomState; 7 8 /// A read-only view into a `DashMap`. Allows to obtain raw references to the stored values. 9 pub struct ReadOnlyView<K, V, S = RandomState> { 10 map: DashMap<K, V, S>, 11 } 12 13 impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for ReadOnlyView<K, V, S> { clone(&self) -> Self14 fn clone(&self) -> Self { 15 Self { 16 map: self.map.clone(), 17 } 18 } 19 } 20 21 impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug 22 for ReadOnlyView<K, V, S> 23 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 25 self.map.fmt(f) 26 } 27 } 28 29 impl<K, V, S> ReadOnlyView<K, V, S> { new(map: DashMap<K, V, S>) -> Self30 pub(crate) fn new(map: DashMap<K, V, S>) -> Self { 31 Self { map } 32 } 33 34 /// Consumes this `ReadOnlyView`, returning the underlying `DashMap`. into_inner(self) -> DashMap<K, V, S>35 pub fn into_inner(self) -> DashMap<K, V, S> { 36 self.map 37 } 38 } 39 40 impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S> { 41 /// Returns the number of elements in the map. len(&self) -> usize42 pub fn len(&self) -> usize { 43 self.map.len() 44 } 45 46 /// Returns `true` if the map contains no elements. is_empty(&self) -> bool47 pub fn is_empty(&self) -> bool { 48 self.map.is_empty() 49 } 50 51 /// Returns the number of elements the map can hold without reallocating. capacity(&self) -> usize52 pub fn capacity(&self) -> usize { 53 self.map.capacity() 54 } 55 56 /// Returns `true` if the map contains a value for the specified key. contains_key<Q>(&'a self, key: &Q) -> bool where K: Borrow<Q>, Q: Hash + Eq + ?Sized,57 pub fn contains_key<Q>(&'a self, key: &Q) -> bool 58 where 59 K: Borrow<Q>, 60 Q: Hash + Eq + ?Sized, 61 { 62 let hash = self.map.hash_usize(&key); 63 64 let idx = self.map.determine_shard(hash); 65 66 let shard = unsafe { self.map._get_read_shard(idx) }; 67 68 shard.contains_key(key) 69 } 70 71 /// Returns a reference to the value corresponding to the key. get<Q>(&'a self, key: &Q) -> Option<&'a V> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,72 pub fn get<Q>(&'a self, key: &Q) -> Option<&'a V> 73 where 74 K: Borrow<Q>, 75 Q: Hash + Eq + ?Sized, 76 { 77 let hash = self.map.hash_usize(&key); 78 79 let idx = self.map.determine_shard(hash); 80 81 let shard = unsafe { self.map._get_read_shard(idx) }; 82 83 shard.get(key).map(|v| v.get()) 84 } 85 86 /// Returns the key-value pair corresponding to the supplied key. get_key_value<Q>(&'a self, key: &Q) -> Option<(&'a K, &'a V)> where K: Borrow<Q>, Q: Hash + Eq + ?Sized,87 pub fn get_key_value<Q>(&'a self, key: &Q) -> Option<(&'a K, &'a V)> 88 where 89 K: Borrow<Q>, 90 Q: Hash + Eq + ?Sized, 91 { 92 let hash = self.map.hash_usize(&key); 93 94 let idx = self.map.determine_shard(hash); 95 96 let shard = unsafe { self.map._get_read_shard(idx) }; 97 98 shard.get_key_value(key).map(|(k, v)| (k, v.get())) 99 } 100 shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a101 fn shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a { 102 (0..self.map._shard_count()) 103 .map(move |shard_i| unsafe { self.map._get_read_shard(shard_i) }) 104 } 105 106 /// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(&'a K, &'a V)`. iter(&'a self) -> impl Iterator<Item = (&'a K, &'a V)> + 'a107 pub fn iter(&'a self) -> impl Iterator<Item = (&'a K, &'a V)> + 'a { 108 self.shard_read_iter() 109 .flat_map(|shard| shard.iter()) 110 .map(|(k, v)| (k, v.get())) 111 } 112 113 /// An iterator visiting all keys in arbitrary order. The iterator element type is `&'a K`. keys(&'a self) -> impl Iterator<Item = &'a K> + 'a114 pub fn keys(&'a self) -> impl Iterator<Item = &'a K> + 'a { 115 self.shard_read_iter().flat_map(|shard| shard.keys()) 116 } 117 118 /// An iterator visiting all values in arbitrary order. The iterator element type is `&'a V`. values(&'a self) -> impl Iterator<Item = &'a V> + 'a119 pub fn values(&'a self) -> impl Iterator<Item = &'a V> + 'a { 120 self.shard_read_iter() 121 .flat_map(|shard| shard.values()) 122 .map(|v| v.get()) 123 } 124 } 125 126 #[cfg(test)] 127 128 mod tests { 129 130 use crate::DashMap; 131 construct_sample_map() -> DashMap<i32, String>132 fn construct_sample_map() -> DashMap<i32, String> { 133 let map = DashMap::new(); 134 135 map.insert(1, "one".to_string()); 136 137 map.insert(10, "ten".to_string()); 138 139 map.insert(27, "twenty seven".to_string()); 140 141 map.insert(45, "forty five".to_string()); 142 143 map 144 } 145 146 #[test] 147 test_properties()148 fn test_properties() { 149 let map = construct_sample_map(); 150 151 let view = map.clone().into_read_only(); 152 153 assert_eq!(view.is_empty(), map.is_empty()); 154 155 assert_eq!(view.len(), map.len()); 156 157 assert_eq!(view.capacity(), map.capacity()); 158 159 let new_map = view.into_inner(); 160 161 assert_eq!(new_map.is_empty(), map.is_empty()); 162 163 assert_eq!(new_map.len(), map.len()); 164 165 assert_eq!(new_map.capacity(), map.capacity()); 166 } 167 168 #[test] 169 test_get()170 fn test_get() { 171 let map = construct_sample_map(); 172 173 let view = map.clone().into_read_only(); 174 175 for key in map.iter().map(|entry| *entry.key()) { 176 assert!(view.contains_key(&key)); 177 178 let map_entry = map.get(&key).unwrap(); 179 180 assert_eq!(view.get(&key).unwrap(), map_entry.value()); 181 182 let key_value: (&i32, &String) = view.get_key_value(&key).unwrap(); 183 184 assert_eq!(key_value.0, map_entry.key()); 185 186 assert_eq!(key_value.1, map_entry.value()); 187 } 188 } 189 190 #[test] 191 test_iters()192 fn test_iters() { 193 let map = construct_sample_map(); 194 195 let view = map.clone().into_read_only(); 196 197 let mut visited_items = Vec::new(); 198 199 for (key, value) in view.iter() { 200 map.contains_key(key); 201 202 let map_entry = map.get(&key).unwrap(); 203 204 assert_eq!(key, map_entry.key()); 205 206 assert_eq!(value, map_entry.value()); 207 208 visited_items.push((key, value)); 209 } 210 211 let mut visited_keys = Vec::new(); 212 213 for key in view.keys() { 214 map.contains_key(key); 215 216 let map_entry = map.get(&key).unwrap(); 217 218 assert_eq!(key, map_entry.key()); 219 220 assert_eq!(view.get(key).unwrap(), map_entry.value()); 221 222 visited_keys.push(key); 223 } 224 225 let mut visited_values = Vec::new(); 226 227 for value in view.values() { 228 visited_values.push(value); 229 } 230 231 for entry in map.iter() { 232 let key = entry.key(); 233 234 let value = entry.value(); 235 236 assert!(visited_keys.contains(&key)); 237 238 assert!(visited_values.contains(&value)); 239 240 assert!(visited_items.contains(&(key, value))); 241 } 242 } 243 } 244