diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /vendor/dashmap/src/mapref | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/dashmap/src/mapref')
-rw-r--r-- | vendor/dashmap/src/mapref/entry.rs | 189 | ||||
-rw-r--r-- | vendor/dashmap/src/mapref/mod.rs | 3 | ||||
-rw-r--r-- | vendor/dashmap/src/mapref/multiple.rs | 107 | ||||
-rw-r--r-- | vendor/dashmap/src/mapref/one.rs | 321 |
4 files changed, 620 insertions, 0 deletions
diff --git a/vendor/dashmap/src/mapref/entry.rs b/vendor/dashmap/src/mapref/entry.rs new file mode 100644 index 000000000..16a42ce77 --- /dev/null +++ b/vendor/dashmap/src/mapref/entry.rs @@ -0,0 +1,189 @@ +use super::one::RefMut; +use crate::lock::RwLockWriteGuard; +use crate::util; +use crate::util::SharedValue; +use crate::HashMap; +use core::hash::{BuildHasher, Hash}; +use core::mem; +use core::ptr; +use std::collections::hash_map::RandomState; + +pub enum Entry<'a, K, V, S = RandomState> { + Occupied(OccupiedEntry<'a, K, V, S>), + Vacant(VacantEntry<'a, K, V, S>), +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> { + /// Apply a function to the stored value if it exists. + pub fn and_modify(self, f: impl FnOnce(&mut V)) -> Self { + match self { + Entry::Occupied(mut entry) => { + f(entry.get_mut()); + + Entry::Occupied(entry) + } + + Entry::Vacant(entry) => Entry::Vacant(entry), + } + } + + /// Get the key of the entry. + pub fn key(&self) -> &K { + match *self { + Entry::Occupied(ref entry) => entry.key(), + Entry::Vacant(ref entry) => entry.key(), + } + } + + /// Into the key of the entry. + pub fn into_key(self) -> K { + match self { + Entry::Occupied(entry) => entry.into_key(), + Entry::Vacant(entry) => entry.into_key(), + } + } + + /// Return a mutable reference to the element if it exists, + /// otherwise insert the default and return a mutable reference to that. + pub fn or_default(self) -> RefMut<'a, K, V, S> + where + V: Default, + { + match self { + Entry::Occupied(entry) => entry.into_ref(), + Entry::Vacant(entry) => entry.insert(V::default()), + } + } + + /// Return a mutable reference to the element if it exists, + /// otherwise a provided value and return a mutable reference to that. + pub fn or_insert(self, value: V) -> RefMut<'a, K, V, S> { + match self { + Entry::Occupied(entry) => entry.into_ref(), + Entry::Vacant(entry) => entry.insert(value), + } + } + + /// Return a mutable reference to the element if it exists, + /// otherwise insert the result of a provided function and return a mutable reference to that. + pub fn or_insert_with(self, value: impl FnOnce() -> V) -> RefMut<'a, K, V, S> { + match self { + Entry::Occupied(entry) => entry.into_ref(), + Entry::Vacant(entry) => entry.insert(value()), + } + } + + pub fn or_try_insert_with<E>( + self, + value: impl FnOnce() -> Result<V, E>, + ) -> Result<RefMut<'a, K, V, S>, E> { + match self { + Entry::Occupied(entry) => Ok(entry.into_ref()), + Entry::Vacant(entry) => Ok(entry.insert(value()?)), + } + } +} + +pub struct VacantEntry<'a, K, V, S = RandomState> { + shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + key: K, +} + +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for VacantEntry<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for VacantEntry<'a, K, V, S> {} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> { + pub(crate) unsafe fn new(shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, key: K) -> Self { + Self { shard, key } + } + + pub fn insert(mut self, value: V) -> RefMut<'a, K, V, S> { + unsafe { + let c: K = ptr::read(&self.key); + + self.shard.insert(self.key, SharedValue::new(value)); + + let (k, v) = self.shard.get_key_value(&c).unwrap(); + + let k = util::change_lifetime_const(k); + + let v = &mut *v.as_ptr(); + + let r = RefMut::new(self.shard, k, v); + + mem::forget(c); + + r + } + } + + pub fn into_key(self) -> K { + self.key + } + + pub fn key(&self) -> &K { + &self.key + } +} + +pub struct OccupiedEntry<'a, K, V, S = RandomState> { + shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + elem: (*const K, *mut V), + key: K, +} + +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for OccupiedEntry<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for OccupiedEntry<'a, K, V, S> {} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> { + pub(crate) unsafe fn new( + shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + key: K, + elem: (*const K, *mut V), + ) -> Self { + Self { shard, elem, key } + } + + pub fn get(&self) -> &V { + unsafe { &*self.elem.1 } + } + + pub fn get_mut(&mut self) -> &mut V { + unsafe { &mut *self.elem.1 } + } + + pub fn insert(&mut self, value: V) -> V { + mem::replace(self.get_mut(), value) + } + + pub fn into_ref(self) -> RefMut<'a, K, V, S> { + unsafe { RefMut::new(self.shard, self.elem.0, self.elem.1) } + } + + pub fn into_key(self) -> K { + self.key + } + + pub fn key(&self) -> &K { + unsafe { &*self.elem.0 } + } + + pub fn remove(mut self) -> V { + let key = unsafe { &*self.elem.0 }; + self.shard.remove(key).unwrap().into_inner() + } + + pub fn remove_entry(mut self) -> (K, V) { + let key = unsafe { &*self.elem.0 }; + let (k, v) = self.shard.remove_entry(key).unwrap(); + (k, v.into_inner()) + } + + pub fn replace_entry(mut self, value: V) -> (K, V) { + let nk = self.key; + let key = unsafe { &*self.elem.0 }; + let (k, v) = self.shard.remove_entry(key).unwrap(); + self.shard.insert(nk, SharedValue::new(value)); + (k, v.into_inner()) + } +} diff --git a/vendor/dashmap/src/mapref/mod.rs b/vendor/dashmap/src/mapref/mod.rs new file mode 100644 index 000000000..8897547e0 --- /dev/null +++ b/vendor/dashmap/src/mapref/mod.rs @@ -0,0 +1,3 @@ +pub mod entry; +pub mod multiple; +pub mod one; diff --git a/vendor/dashmap/src/mapref/multiple.rs b/vendor/dashmap/src/mapref/multiple.rs new file mode 100644 index 000000000..53a8a7e58 --- /dev/null +++ b/vendor/dashmap/src/mapref/multiple.rs @@ -0,0 +1,107 @@ +use crate::lock::{RwLockReadGuard, RwLockWriteGuard}; +use crate::HashMap; +use core::hash::BuildHasher; +use core::hash::Hash; +use core::ops::{Deref, DerefMut}; +use std::collections::hash_map::RandomState; +use std::sync::Arc; + +pub struct RefMulti<'a, K, V, S = RandomState> { + _guard: Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>, + k: *const K, + v: *const V, +} + +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for RefMulti<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for RefMulti<'a, K, V, S> {} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> { + pub(crate) unsafe fn new( + guard: Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>, + k: *const K, + v: *const V, + ) -> Self { + Self { + _guard: guard, + k, + v, + } + } + + pub fn key(&self) -> &K { + self.pair().0 + } + + pub fn value(&self) -> &V { + self.pair().1 + } + + pub fn pair(&self) -> (&K, &V) { + unsafe { (&*self.k, &*self.v) } + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMulti<'a, K, V, S> { + type Target = V; + + fn deref(&self) -> &V { + self.value() + } +} + +pub struct RefMutMulti<'a, K, V, S = RandomState> { + _guard: Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>, + k: *const K, + v: *mut V, +} + +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for RefMutMulti<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for RefMutMulti<'a, K, V, S> {} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> { + pub(crate) unsafe fn new( + guard: Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>, + k: *const K, + v: *mut V, + ) -> Self { + Self { + _guard: guard, + k, + v, + } + } + + pub fn key(&self) -> &K { + self.pair().0 + } + + pub fn value(&self) -> &V { + self.pair().1 + } + + pub fn value_mut(&mut self) -> &mut V { + self.pair_mut().1 + } + + pub fn pair(&self) -> (&K, &V) { + unsafe { (&*self.k, &*self.v) } + } + + pub fn pair_mut(&mut self) -> (&K, &mut V) { + unsafe { (&*self.k, &mut *self.v) } + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMutMulti<'a, K, V, S> { + type Target = V; + + fn deref(&self) -> &V { + self.value() + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMutMulti<'a, K, V, S> { + fn deref_mut(&mut self) -> &mut V { + self.value_mut() + } +} diff --git a/vendor/dashmap/src/mapref/one.rs b/vendor/dashmap/src/mapref/one.rs new file mode 100644 index 000000000..835e45cad --- /dev/null +++ b/vendor/dashmap/src/mapref/one.rs @@ -0,0 +1,321 @@ +use crate::lock::{RwLockReadGuard, RwLockWriteGuard}; +use crate::HashMap; +use core::hash::{BuildHasher, Hash}; +use core::ops::{Deref, DerefMut}; +use std::collections::hash_map::RandomState; +use std::fmt::{Debug, Formatter}; + +pub struct Ref<'a, K, V, S = RandomState> { + _guard: RwLockReadGuard<'a, HashMap<K, V, S>>, + k: *const K, + v: *const V, +} + +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for Ref<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for Ref<'a, K, V, S> {} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Ref<'a, K, V, S> { + pub(crate) unsafe fn new( + guard: RwLockReadGuard<'a, HashMap<K, V, S>>, + k: *const K, + v: *const V, + ) -> Self { + Self { + _guard: guard, + k, + v, + } + } + + pub fn key(&self) -> &K { + self.pair().0 + } + + pub fn value(&self) -> &V { + self.pair().1 + } + + pub fn pair(&self) -> (&K, &V) { + unsafe { (&*self.k, &*self.v) } + } + + pub fn map<F, T>(self, f: F) -> MappedRef<'a, K, V, T, S> + where + F: FnOnce(&V) -> &T, + { + MappedRef { + _guard: self._guard, + k: self.k, + v: f(unsafe { &*self.v }), + } + } + + pub fn try_map<F, T>(self, f: F) -> Result<MappedRef<'a, K, V, T, S>, Self> + where + F: FnOnce(&V) -> Option<&T>, + { + if let Some(v) = f(unsafe { &*self.v }) { + Ok(MappedRef { + _guard: self._guard, + k: self.k, + v, + }) + } else { + Err(self) + } + } +} + +impl<'a, K: Eq + Hash + Debug, V: Debug, S: BuildHasher> Debug for Ref<'a, K, V, S> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Ref") + .field("k", &self.k) + .field("v", &self.v) + .finish() + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for Ref<'a, K, V, S> { + type Target = V; + + fn deref(&self) -> &V { + self.value() + } +} + +pub struct RefMut<'a, K, V, S = RandomState> { + guard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + k: *const K, + v: *mut V, +} + +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Send for RefMut<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Sync, V: Sync, S: BuildHasher> Sync for RefMut<'a, K, V, S> {} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMut<'a, K, V, S> { + pub(crate) unsafe fn new( + guard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + k: *const K, + v: *mut V, + ) -> Self { + Self { guard, k, v } + } + + pub fn key(&self) -> &K { + self.pair().0 + } + + pub fn value(&self) -> &V { + self.pair().1 + } + + pub fn value_mut(&mut self) -> &mut V { + self.pair_mut().1 + } + + pub fn pair(&self) -> (&K, &V) { + unsafe { (&*self.k, &*self.v) } + } + + pub fn pair_mut(&mut self) -> (&K, &mut V) { + unsafe { (&*self.k, &mut *self.v) } + } + + pub fn downgrade(self) -> Ref<'a, K, V, S> { + unsafe { Ref::new(RwLockWriteGuard::downgrade(self.guard), self.k, self.v) } + } + + pub fn map<F, T>(self, f: F) -> MappedRefMut<'a, K, V, T, S> + where + F: FnOnce(&mut V) -> &mut T, + { + MappedRefMut { + _guard: self.guard, + k: self.k, + v: f(unsafe { &mut *self.v }), + } + } + + pub fn try_map<F, T>(self, f: F) -> Result<MappedRefMut<'a, K, V, T, S>, Self> + where + F: FnOnce(&mut V) -> Option<&mut T>, + { + let v = match f(unsafe { &mut *(self.v as *mut _) }) { + Some(v) => v, + None => return Err(self), + }; + let guard = self.guard; + let k = self.k; + Ok(MappedRefMut { + _guard: guard, + k, + v, + }) + } +} + +impl<'a, K: Eq + Hash + Debug, V: Debug, S: BuildHasher> Debug for RefMut<'a, K, V, S> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("RefMut") + .field("k", &self.k) + .field("v", &self.v) + .finish() + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMut<'a, K, V, S> { + type Target = V; + + fn deref(&self) -> &V { + self.value() + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMut<'a, K, V, S> { + fn deref_mut(&mut self) -> &mut V { + self.value_mut() + } +} + +pub struct MappedRef<'a, K, V, T, S = RandomState> { + _guard: RwLockReadGuard<'a, HashMap<K, V, S>>, + k: *const K, + v: *const T, +} + +impl<'a, K: Eq + Hash, V, T, S: BuildHasher> MappedRef<'a, K, V, T, S> { + pub fn key(&self) -> &K { + self.pair().0 + } + + pub fn value(&self) -> &T { + self.pair().1 + } + + pub fn pair(&self) -> (&K, &T) { + unsafe { (&*self.k, &*self.v) } + } + + pub fn map<F, T2>(self, f: F) -> MappedRef<'a, K, V, T2, S> + where + F: FnOnce(&T) -> &T2, + { + MappedRef { + _guard: self._guard, + k: self.k, + v: f(unsafe { &*self.v }), + } + } + + pub fn try_map<F, T2>(self, f: F) -> Result<MappedRef<'a, K, V, T2, S>, Self> + where + F: FnOnce(&T) -> Option<&T2>, + { + let v = match f(unsafe { &*self.v }) { + Some(v) => v, + None => return Err(self), + }; + let guard = self._guard; + Ok(MappedRef { + _guard: guard, + k: self.k, + v, + }) + } +} + +impl<'a, K: Eq + Hash + Debug, V, T: Debug, S: BuildHasher> Debug for MappedRef<'a, K, V, T, S> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MappedRef") + .field("k", &self.k) + .field("v", &self.v) + .finish() + } +} + +impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRef<'a, K, V, T, S> { + type Target = T; + + fn deref(&self) -> &T { + self.value() + } +} + +pub struct MappedRefMut<'a, K, V, T, S = RandomState> { + _guard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + k: *const K, + v: *mut T, +} + +impl<'a, K: Eq + Hash, V, T, S: BuildHasher> MappedRefMut<'a, K, V, T, S> { + pub fn key(&self) -> &K { + self.pair().0 + } + + pub fn value(&self) -> &T { + self.pair().1 + } + + pub fn value_mut(&mut self) -> &mut T { + self.pair_mut().1 + } + + pub fn pair(&self) -> (&K, &T) { + unsafe { (&*self.k, &*self.v) } + } + + pub fn pair_mut(&mut self) -> (&K, &mut T) { + unsafe { (&*self.k, &mut *self.v) } + } + + pub fn map<F, T2>(self, f: F) -> MappedRefMut<'a, K, V, T2, S> + where + F: FnOnce(&mut T) -> &mut T2, + { + MappedRefMut { + _guard: self._guard, + k: self.k, + v: f(unsafe { &mut *self.v }), + } + } + + pub fn try_map<F, T2>(self, f: F) -> Result<MappedRefMut<'a, K, V, T2, S>, Self> + where + F: FnOnce(&mut T) -> Option<&mut T2>, + { + let v = match f(unsafe { &mut *(self.v as *mut _) }) { + Some(v) => v, + None => return Err(self), + }; + let guard = self._guard; + let k = self.k; + Ok(MappedRefMut { + _guard: guard, + k, + v, + }) + } +} + +impl<'a, K: Eq + Hash + Debug, V, T: Debug, S: BuildHasher> Debug for MappedRefMut<'a, K, V, T, S> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MappedRefMut") + .field("k", &self.k) + .field("v", &self.v) + .finish() + } +} + +impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRefMut<'a, K, V, T, S> { + type Target = T; + + fn deref(&self) -> &T { + self.value() + } +} + +impl<'a, K: Eq + Hash, V, T, S: BuildHasher> DerefMut for MappedRefMut<'a, K, V, T, S> { + fn deref_mut(&mut self) -> &mut T { + self.value_mut() + } +} |