1 use crate::lock::RwLock; 2 use crate::t::Map; 3 use crate::{DashMap, HashMap}; 4 use cfg_if::cfg_if; 5 use core::borrow::Borrow; 6 use core::fmt; 7 use core::hash::{BuildHasher, Hash}; 8 use std::collections::hash_map::RandomState; 9 10 /// A read-only view into a `DashMap`. Allows to obtain raw references to the stored values. 11 pub struct ReadOnlyView<K, V, S = RandomState> { 12 pub(crate) map: DashMap<K, V, S>, 13 } 14 15 impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for ReadOnlyView<K, V, S> { clone(&self) -> Self16 fn clone(&self) -> Self { 17 Self { 18 map: self.map.clone(), 19 } 20 } 21 } 22 23 impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug 24 for ReadOnlyView<K, V, S> 25 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 27 self.map.fmt(f) 28 } 29 } 30 31 impl<K, V, S> ReadOnlyView<K, V, S> { new(map: DashMap<K, V, S>) -> Self32 pub(crate) fn new(map: DashMap<K, V, S>) -> Self { 33 Self { map } 34 } 35 36 /// Consumes this `ReadOnlyView`, returning the underlying `DashMap`. into_inner(self) -> DashMap<K, V, S>37 pub fn into_inner(self) -> DashMap<K, V, S> { 38 self.map 39 } 40 } 41 42 impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S> { 43 /// Returns the number of elements in the map. len(&self) -> usize44 pub fn len(&self) -> usize { 45 self.map.len() 46 } 47 48 /// Returns `true` if the map contains no elements. is_empty(&self) -> bool49 pub fn is_empty(&self) -> bool { 50 self.map.is_empty() 51 } 52 53 /// Returns the number of elements the map can hold without reallocating. capacity(&self) -> usize54 pub fn capacity(&self) -> usize { 55 self.map.capacity() 56 } 57 58 /// 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,59 pub fn contains_key<Q>(&'a self, key: &Q) -> bool 60 where 61 K: Borrow<Q>, 62 Q: Hash + Eq + ?Sized, 63 { 64 let hash = self.map.hash_usize(&key); 65 66 let idx = self.map.determine_shard(hash); 67 68 let shard = unsafe { self.map._get_read_shard(idx) }; 69 70 shard.contains_key(key) 71 } 72 73 /// 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,74 pub fn get<Q>(&'a self, key: &Q) -> Option<&'a V> 75 where 76 K: Borrow<Q>, 77 Q: Hash + Eq + ?Sized, 78 { 79 let hash = self.map.hash_usize(&key); 80 81 let idx = self.map.determine_shard(hash); 82 83 let shard = unsafe { self.map._get_read_shard(idx) }; 84 85 shard.get(key).map(|v| v.get()) 86 } 87 88 /// 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,89 pub fn get_key_value<Q>(&'a self, key: &Q) -> Option<(&'a K, &'a V)> 90 where 91 K: Borrow<Q>, 92 Q: Hash + Eq + ?Sized, 93 { 94 let hash = self.map.hash_usize(&key); 95 96 let idx = self.map.determine_shard(hash); 97 98 let shard = unsafe { self.map._get_read_shard(idx) }; 99 100 shard.get_key_value(key).map(|(k, v)| (k, v.get())) 101 } 102 shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a103 fn shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a { 104 (0..self.map._shard_count()) 105 .map(move |shard_i| unsafe { self.map._get_read_shard(shard_i) }) 106 } 107 108 /// 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)> + 'a109 pub fn iter(&'a self) -> impl Iterator<Item = (&'a K, &'a V)> + 'a { 110 self.shard_read_iter() 111 .flat_map(|shard| shard.iter()) 112 .map(|(k, v)| (k, v.get())) 113 } 114 115 /// An iterator visiting all keys in arbitrary order. The iterator element type is `&'a K`. keys(&'a self) -> impl Iterator<Item = &'a K> + 'a116 pub fn keys(&'a self) -> impl Iterator<Item = &'a K> + 'a { 117 self.shard_read_iter().flat_map(|shard| shard.keys()) 118 } 119 120 /// An iterator visiting all values in arbitrary order. The iterator element type is `&'a V`. values(&'a self) -> impl Iterator<Item = &'a V> + 'a121 pub fn values(&'a self) -> impl Iterator<Item = &'a V> + 'a { 122 self.shard_read_iter() 123 .flat_map(|shard| shard.values()) 124 .map(|v| v.get()) 125 } 126 127 cfg_if! { 128 if #[cfg(feature = "raw-api")] { 129 /// Allows you to peek at the inner shards that store your data. 130 /// You should probably not use this unless you know what you are doing. 131 /// 132 /// Requires the `raw-api` feature to be enabled. 133 /// 134 /// # Examples 135 /// 136 /// ``` 137 /// use dashmap::DashMap; 138 /// 139 /// let map = DashMap::<(), ()>::new().into_read_only(); 140 /// println!("Amount of shards: {}", map.shards().len()); 141 /// ``` 142 pub fn shards(&self) -> &[RwLock<HashMap<K, V, S>>] { 143 &self.map.shards 144 } 145 } else { 146 #[allow(dead_code)] 147 pub(crate) fn shards(&self) -> &[RwLock<HashMap<K, V, S>>] { 148 &self.map.shards 149 } 150 } 151 } 152 } 153 154 #[cfg(test)] 155 156 mod tests { 157 158 use crate::DashMap; 159 construct_sample_map() -> DashMap<i32, String>160 fn construct_sample_map() -> DashMap<i32, String> { 161 let map = DashMap::new(); 162 163 map.insert(1, "one".to_string()); 164 165 map.insert(10, "ten".to_string()); 166 167 map.insert(27, "twenty seven".to_string()); 168 169 map.insert(45, "forty five".to_string()); 170 171 map 172 } 173 174 #[test] 175 test_properties()176 fn test_properties() { 177 let map = construct_sample_map(); 178 179 let view = map.clone().into_read_only(); 180 181 assert_eq!(view.is_empty(), map.is_empty()); 182 183 assert_eq!(view.len(), map.len()); 184 185 assert_eq!(view.capacity(), map.capacity()); 186 187 let new_map = view.into_inner(); 188 189 assert_eq!(new_map.is_empty(), map.is_empty()); 190 191 assert_eq!(new_map.len(), map.len()); 192 193 assert_eq!(new_map.capacity(), map.capacity()); 194 } 195 196 #[test] 197 test_get()198 fn test_get() { 199 let map = construct_sample_map(); 200 201 let view = map.clone().into_read_only(); 202 203 for key in map.iter().map(|entry| *entry.key()) { 204 assert!(view.contains_key(&key)); 205 206 let map_entry = map.get(&key).unwrap(); 207 208 assert_eq!(view.get(&key).unwrap(), map_entry.value()); 209 210 let key_value: (&i32, &String) = view.get_key_value(&key).unwrap(); 211 212 assert_eq!(key_value.0, map_entry.key()); 213 214 assert_eq!(key_value.1, map_entry.value()); 215 } 216 } 217 218 #[test] 219 test_iters()220 fn test_iters() { 221 let map = construct_sample_map(); 222 223 let view = map.clone().into_read_only(); 224 225 let mut visited_items = Vec::new(); 226 227 for (key, value) in view.iter() { 228 map.contains_key(key); 229 230 let map_entry = map.get(key).unwrap(); 231 232 assert_eq!(key, map_entry.key()); 233 234 assert_eq!(value, map_entry.value()); 235 236 visited_items.push((key, value)); 237 } 238 239 let mut visited_keys = Vec::new(); 240 241 for key in view.keys() { 242 map.contains_key(key); 243 244 let map_entry = map.get(key).unwrap(); 245 246 assert_eq!(key, map_entry.key()); 247 248 assert_eq!(view.get(key).unwrap(), map_entry.value()); 249 250 visited_keys.push(key); 251 } 252 253 let mut visited_values = Vec::new(); 254 255 for value in view.values() { 256 visited_values.push(value); 257 } 258 259 for entry in map.iter() { 260 let key = entry.key(); 261 262 let value = entry.value(); 263 264 assert!(visited_keys.contains(&key)); 265 266 assert!(visited_values.contains(&value)); 267 268 assert!(visited_items.contains(&(key, value))); 269 } 270 } 271 } 272