1use super::one::RefMut;
2use crate::util;
3use crate::util::SharedValue;
4use crate::HashMap;
5use core::hash::{BuildHasher, Hash};
6use core::mem;
7use core::ptr;
8use parking_lot::RwLockWriteGuard;
9use std::collections::hash_map::RandomState;
10
11pub enum Entry<'a, K, V, S = RandomState> {
12 Occupied(OccupiedEntry<'a, K, V, S>),
13 Vacant(VacantEntry<'a, K, V, S>),
14}
15
16impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
17 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 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 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 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 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 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
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
87pub struct VacantEntry<'a, K, V, S> {
88 shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
89 key: K,
90}
91
92unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for VacantEntry<'a, K, V, S> {}
93
94unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
95 for VacantEntry<'a, K, V, S>
96{
97}
98
99impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
100 pub(crate) unsafe fn new(shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, key: K) -> Self {
101 Self { shard, key }
102 }
103
104 pub fn insert(mut self, value: V) -> RefMut<'a, K, V, S> {
105 unsafe {
106 let c: K = ptr::read(&self.key);
107
108 self.shard.insert(self.key, SharedValue::new(value));
109
110 let (k, v) = self.shard.get_key_value(&c).unwrap();
111
112 let k = util::change_lifetime_const(k);
113
114 let v = &mut *v.as_ptr();
115
116 let r = RefMut::new(self.shard, k, v);
117
118 mem::forget(c);
119
120 r
121 }
122 }
123
124 pub fn into_key(self) -> K {
125 self.key
126 }
127
128 pub fn key(&self) -> &K {
129 &self.key
130 }
131}
132
133pub struct OccupiedEntry<'a, K, V, S> {
134 shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
135 elem: (*const K, *mut V),
136 key: K,
137}
138
139unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for OccupiedEntry<'a, K, V, S> {}
140
141unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
142 for OccupiedEntry<'a, K, V, S>
143{
144}
145
146impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
147 pub(crate) unsafe fn new(
148 shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
149 key: K,
150 elem: (*const K, *mut V),
151 ) -> Self {
152 Self { shard, elem, key }
153 }
154
155 pub fn get(&self) -> &V {
156 unsafe { &*self.elem.1 }
157 }
158
159 pub fn get_mut(&mut self) -> &mut V {
160 unsafe { &mut *self.elem.1 }
161 }
162
163 pub fn insert(&mut self, value: V) -> V {
164 mem::replace(self.get_mut(), value)
165 }
166
167 pub fn into_ref(self) -> RefMut<'a, K, V, S> {
168 unsafe { RefMut::new(self.shard, self.elem.0, self.elem.1) }
169 }
170
171 pub fn into_key(self) -> K {
172 self.key
173 }
174
175 pub fn key(&self) -> &K {
176 unsafe { &*self.elem.0 }
177 }
178
179 pub fn remove(mut self) -> V {
180 let key = unsafe { &*self.elem.0 };
181 self.shard.remove(key).unwrap().into_inner()
182 }
183
184 pub fn remove_entry(mut self) -> (K, V) {
185 let key = unsafe { &*self.elem.0 };
186 let (k, v) = self.shard.remove_entry(key).unwrap();
187 (k, v.into_inner())
188 }
189
190 pub fn replace_entry(mut self, value: V) -> (K, V) {
191 let nk = self.key;
192 let key = unsafe { &*self.elem.0 };
193 let (k, v) = self.shard.remove_entry(key).unwrap();
194 self.shard.insert(nk, SharedValue::new(value));
195 (k, v.into_inner())
196 }
197}