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