1 use super::one::RefMut;
2 use crate::lock::RwLockWriteGuard;
3 use crate::util;
4 use crate::util::SharedValue;
5 use crate::HashMap;
6 use core::hash::{BuildHasher, Hash};
7 use core::mem;
8 use core::ptr;
9 use std::collections::hash_map::RandomState;
10 
11 pub enum Entry<'a, K, V, S = RandomState> {
12     Occupied(OccupiedEntry<'a, K, V, S>),
13     Vacant(VacantEntry<'a, K, V, S>),
14 }
15 
16 impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
17     /// Apply a function to the stored value if it exists.
and_modify(self, f: impl FnOnce(&mut V)) -> Self18     pub fn and_modify(self, f: impl FnOnce(&mut V)) -> Self {
19         match self {
20             Entry::Occupied(mut entry) => {
21                 f(entry.get_mut());
22 
23                 Entry::Occupied(entry)
24             }
25 
26             Entry::Vacant(entry) => Entry::Vacant(entry),
27         }
28     }
29 
30     /// Get the key of the entry.
key(&self) -> &K31     pub fn key(&self) -> &K {
32         match *self {
33             Entry::Occupied(ref entry) => entry.key(),
34             Entry::Vacant(ref entry) => entry.key(),
35         }
36     }
37 
38     /// Into the key of the entry.
into_key(self) -> K39     pub fn into_key(self) -> K {
40         match self {
41             Entry::Occupied(entry) => entry.into_key(),
42             Entry::Vacant(entry) => entry.into_key(),
43         }
44     }
45 
46     /// Return a mutable reference to the element if it exists,
47     /// otherwise insert the default and return a mutable reference to that.
or_default(self) -> RefMut<'a, K, V, S> where V: Default,48     pub fn or_default(self) -> RefMut<'a, K, V, S>
49     where
50         V: Default,
51     {
52         match self {
53             Entry::Occupied(entry) => entry.into_ref(),
54             Entry::Vacant(entry) => entry.insert(V::default()),
55         }
56     }
57 
58     /// Return a mutable reference to the element if it exists,
59     /// otherwise a provided value and return a mutable reference to that.
or_insert(self, value: V) -> RefMut<'a, K, V, S>60     pub fn or_insert(self, value: V) -> RefMut<'a, K, V, S> {
61         match self {
62             Entry::Occupied(entry) => entry.into_ref(),
63             Entry::Vacant(entry) => entry.insert(value),
64         }
65     }
66 
67     /// Return a mutable reference to the element if it exists,
68     /// otherwise insert the result of a provided function and return a mutable reference to that.
or_insert_with(self, value: impl FnOnce() -> V) -> RefMut<'a, K, V, S>69     pub fn or_insert_with(self, value: impl FnOnce() -> V) -> RefMut<'a, K, V, S> {
70         match self {
71             Entry::Occupied(entry) => entry.into_ref(),
72             Entry::Vacant(entry) => entry.insert(value()),
73         }
74     }
75 
or_try_insert_with<E>( self, value: impl FnOnce() -> Result<V, E>, ) -> Result<RefMut<'a, K, V, S>, E>76     pub fn or_try_insert_with<E>(
77         self,
78         value: impl FnOnce() -> Result<V, E>,
79     ) -> Result<RefMut<'a, K, V, S>, E> {
80         match self {
81             Entry::Occupied(entry) => Ok(entry.into_ref()),
82             Entry::Vacant(entry) => Ok(entry.insert(value()?)),
83         }
84     }
85 
86     /// Sets the value of the entry, and returns a reference to the inserted value.
insert(self, value: V) -> RefMut<'a, K, V, S>87     pub fn insert(self, value: V) -> RefMut<'a, K, V, S> {
88         match self {
89             Entry::Occupied(mut entry) => {
90                 entry.insert(value);
91                 entry.into_ref()
92             }
93             Entry::Vacant(entry) => entry.insert(value),
94         }
95     }
96 
97     /// Sets the value of the entry, and returns an OccupiedEntry.
98     ///
99     /// If you are not interested in the occupied entry,
100     /// consider [`insert`] as it doesn't need to clone the key.
101     ///
102     /// [`insert`]: Entry::insert
insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S> where K: Clone,103     pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S>
104     where
105         K: Clone,
106     {
107         match self {
108             Entry::Occupied(mut entry) => {
109                 entry.insert(value);
110                 entry
111             }
112             Entry::Vacant(entry) => entry.insert_entry(value),
113         }
114     }
115 }
116 
117 pub struct VacantEntry<'a, K, V, S = RandomState> {
118     shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
119     key: K,
120 }
121 
122 unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for VacantEntry<'a, K, V, S> {}
123 unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for VacantEntry<'a, K, V, S> {}
124 
125 impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
new(shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, key: K) -> Self126     pub(crate) unsafe fn new(shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, key: K) -> Self {
127         Self { shard, key }
128     }
129 
insert(mut self, value: V) -> RefMut<'a, K, V, S>130     pub fn insert(mut self, value: V) -> RefMut<'a, K, V, S> {
131         unsafe {
132             let c: K = ptr::read(&self.key);
133 
134             self.shard.insert(self.key, SharedValue::new(value));
135 
136             let (k, v) = self.shard.get_key_value(&c).unwrap();
137 
138             let k = util::change_lifetime_const(k);
139 
140             let v = &mut *v.as_ptr();
141 
142             let r = RefMut::new(self.shard, k, v);
143 
144             mem::forget(c);
145 
146             r
147         }
148     }
149 
150     /// Sets the value of the entry with the VacantEntry’s key, and returns an OccupiedEntry.
insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, S> where K: Clone,151     pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, S>
152     where
153         K: Clone,
154     {
155         unsafe {
156             self.shard.insert(self.key.clone(), SharedValue::new(value));
157 
158             let (k, v) = self.shard.get_key_value(&self.key).unwrap();
159 
160             let kptr: *const K = k;
161             let vptr: *mut V = v.as_ptr();
162             OccupiedEntry::new(self.shard, self.key, (kptr, vptr))
163         }
164     }
165 
into_key(self) -> K166     pub fn into_key(self) -> K {
167         self.key
168     }
169 
key(&self) -> &K170     pub fn key(&self) -> &K {
171         &self.key
172     }
173 }
174 
175 pub struct OccupiedEntry<'a, K, V, S = RandomState> {
176     shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
177     elem: (*const K, *mut V),
178     key: K,
179 }
180 
181 unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for OccupiedEntry<'a, K, V, S> {}
182 unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for OccupiedEntry<'a, K, V, S> {}
183 
184 impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
new( shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, key: K, elem: (*const K, *mut V), ) -> Self185     pub(crate) unsafe fn new(
186         shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
187         key: K,
188         elem: (*const K, *mut V),
189     ) -> Self {
190         Self { shard, elem, key }
191     }
192 
get(&self) -> &V193     pub fn get(&self) -> &V {
194         unsafe { &*self.elem.1 }
195     }
196 
get_mut(&mut self) -> &mut V197     pub fn get_mut(&mut self) -> &mut V {
198         unsafe { &mut *self.elem.1 }
199     }
200 
insert(&mut self, value: V) -> V201     pub fn insert(&mut self, value: V) -> V {
202         mem::replace(self.get_mut(), value)
203     }
204 
into_ref(self) -> RefMut<'a, K, V, S>205     pub fn into_ref(self) -> RefMut<'a, K, V, S> {
206         unsafe { RefMut::new(self.shard, self.elem.0, self.elem.1) }
207     }
208 
into_key(self) -> K209     pub fn into_key(self) -> K {
210         self.key
211     }
212 
key(&self) -> &K213     pub fn key(&self) -> &K {
214         unsafe { &*self.elem.0 }
215     }
216 
remove(mut self) -> V217     pub fn remove(mut self) -> V {
218         let key = unsafe { &*self.elem.0 };
219         self.shard.remove(key).unwrap().into_inner()
220     }
221 
remove_entry(mut self) -> (K, V)222     pub fn remove_entry(mut self) -> (K, V) {
223         let key = unsafe { &*self.elem.0 };
224         let (k, v) = self.shard.remove_entry(key).unwrap();
225         (k, v.into_inner())
226     }
227 
replace_entry(mut self, value: V) -> (K, V)228     pub fn replace_entry(mut self, value: V) -> (K, V) {
229         let nk = self.key;
230         let key = unsafe { &*self.elem.0 };
231         let (k, v) = self.shard.remove_entry(key).unwrap();
232         self.shard.insert(nk, SharedValue::new(value));
233         (k, v.into_inner())
234     }
235 }
236 
237 #[cfg(test)]
238 mod tests {
239     use crate::DashMap;
240 
241     use super::*;
242 
243     #[test]
test_insert_entry_into_vacant()244     fn test_insert_entry_into_vacant() {
245         let map: DashMap<u32, u32> = DashMap::new();
246 
247         let entry = map.entry(1);
248 
249         assert!(matches!(entry, Entry::Vacant(_)));
250 
251         let entry = entry.insert_entry(2);
252 
253         assert_eq!(*entry.get(), 2);
254 
255         drop(entry);
256 
257         assert_eq!(*map.get(&1).unwrap(), 2);
258     }
259 
260     #[test]
test_insert_entry_into_occupied()261     fn test_insert_entry_into_occupied() {
262         let map: DashMap<u32, u32> = DashMap::new();
263 
264         map.insert(1, 1000);
265 
266         let entry = map.entry(1);
267 
268         assert!(matches!(&entry, Entry::Occupied(entry) if *entry.get() == 1000));
269 
270         let entry = entry.insert_entry(2);
271 
272         assert_eq!(*entry.get(), 2);
273 
274         drop(entry);
275 
276         assert_eq!(*map.get(&1).unwrap(), 2);
277     }
278 }
279