diff options
Diffstat (limited to 'third_party/rust/dashmap/src/mapref')
-rw-r--r-- | third_party/rust/dashmap/src/mapref/entry.rs | 198 | ||||
-rw-r--r-- | third_party/rust/dashmap/src/mapref/mod.rs | 3 | ||||
-rw-r--r-- | third_party/rust/dashmap/src/mapref/multiple.rs | 120 | ||||
-rw-r--r-- | third_party/rust/dashmap/src/mapref/one.rs | 114 |
4 files changed, 435 insertions, 0 deletions
diff --git a/third_party/rust/dashmap/src/mapref/entry.rs b/third_party/rust/dashmap/src/mapref/entry.rs new file mode 100644 index 0000000000..7a609ee61a --- /dev/null +++ b/third_party/rust/dashmap/src/mapref/entry.rs @@ -0,0 +1,198 @@ +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> { + shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + key: K, +} + +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for VacantEntry<'a, K, V, S> {} + +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + 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) 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> { + shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + elem: (&'a K, &'a mut V), + key: K, +} + +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for OccupiedEntry<'a, K, V, S> {} + +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + 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) fn new( + shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + key: K, + elem: (&'a K, &'a mut V), + ) -> Self { + Self { shard, elem, key } + } + + pub fn get(&self) -> &V { + self.elem.1 + } + + pub fn get_mut(&mut self) -> &mut V { + self.elem.1 + } + + pub fn insert(&mut self, value: V) -> V { + mem::replace(self.elem.1, value) + } + + pub fn into_ref(self) -> RefMut<'a, K, V, S> { + RefMut::new(self.shard, self.elem.0, self.elem.1) + } + + pub fn into_key(self) -> K { + self.key + } + + pub fn key(&self) -> &K { + self.elem.0 + } + + pub fn remove(mut self) -> V { + self.shard.remove(self.elem.0).unwrap().into_inner() + } + + pub fn remove_entry(mut self) -> (K, V) { + let (k, v) = self.shard.remove_entry(self.elem.0).unwrap(); + + (k, v.into_inner()) + } + + pub fn replace_entry(mut self, value: V) -> (K, V) { + let nk = self.key; + + let (k, v) = self.shard.remove_entry(self.elem.0).unwrap(); + + self.shard.insert(nk, SharedValue::new(value)); + + (k, v.into_inner()) + } +} diff --git a/third_party/rust/dashmap/src/mapref/mod.rs b/third_party/rust/dashmap/src/mapref/mod.rs new file mode 100644 index 0000000000..8897547e01 --- /dev/null +++ b/third_party/rust/dashmap/src/mapref/mod.rs @@ -0,0 +1,3 @@ +pub mod entry; +pub mod multiple; +pub mod one; diff --git a/third_party/rust/dashmap/src/mapref/multiple.rs b/third_party/rust/dashmap/src/mapref/multiple.rs new file mode 100644 index 0000000000..4d30aee46f --- /dev/null +++ b/third_party/rust/dashmap/src/mapref/multiple.rs @@ -0,0 +1,120 @@ +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; + +// -- Shared +pub struct RefMulti<'a, K, V, S = RandomState> { + _guard: Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>, + k: &'a K, + v: &'a V, +} + +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for RefMulti<'a, K, V, S> {} + +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + 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) fn new( + guard: Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>, + k: &'a K, + v: &'a V, + ) -> Self { + Self { + _guard: guard, + k, + v, + } + } + + pub fn key(&self) -> &K { + self.k + } + + pub fn value(&self) -> &V { + self.v + } + + pub fn pair(&self) -> (&K, &V) { + (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() + } +} + +// -- +// -- Unique +pub struct RefMutMulti<'a, K, V, S = RandomState> { + _guard: Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>, + k: &'a K, + v: &'a mut V, +} + +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for RefMutMulti<'a, K, V, S> {} + +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + 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) fn new( + guard: Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>, + k: &'a K, + v: &'a mut V, + ) -> Self { + Self { + _guard: guard, + k, + v, + } + } + + pub fn key(&self) -> &K { + self.k + } + + pub fn value(&self) -> &V { + self.v + } + + pub fn value_mut(&mut self) -> &mut V { + self.v + } + + pub fn pair(&self) -> (&K, &V) { + (self.k, self.v) + } + + pub fn pair_mut(&mut self) -> (&K, &mut V) { + (self.k, 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/third_party/rust/dashmap/src/mapref/one.rs b/third_party/rust/dashmap/src/mapref/one.rs new file mode 100644 index 0000000000..67c1706ef8 --- /dev/null +++ b/third_party/rust/dashmap/src/mapref/one.rs @@ -0,0 +1,114 @@ +use crate::lock::{RwLockReadGuard, RwLockWriteGuard}; +use crate::HashMap; +use core::hash::{BuildHasher, Hash}; +use core::ops::{Deref, DerefMut}; +use std::collections::hash_map::RandomState; + +// -- Shared +pub struct Ref<'a, K, V, S = RandomState> { + _guard: RwLockReadGuard<'a, HashMap<K, V, S>>, + k: &'a K, + v: &'a V, +} + +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for Ref<'a, K, V, S> {} + +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + 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) fn new(guard: RwLockReadGuard<'a, HashMap<K, V, S>>, k: &'a K, v: &'a V) -> Self { + Self { + _guard: guard, + k, + v, + } + } + + pub fn key(&self) -> &K { + self.k + } + + pub fn value(&self) -> &V { + self.v + } + + pub fn pair(&self) -> (&K, &V) { + (self.k, self.v) + } +} + +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for Ref<'a, K, V, S> { + type Target = V; + + fn deref(&self) -> &V { + self.value() + } +} + +// -- +// -- Unique +pub struct RefMut<'a, K, V, S = RandomState> { + guard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + k: &'a K, + v: &'a mut V, +} + +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for RefMut<'a, K, V, S> {} + +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + 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) fn new( + guard: RwLockWriteGuard<'a, HashMap<K, V, S>>, + k: &'a K, + v: &'a mut V, + ) -> Self { + Self { guard, k, v } + } + + pub fn key(&self) -> &K { + self.k + } + + pub fn value(&self) -> &V { + self.v + } + + pub fn value_mut(&mut self) -> &mut V { + self.v + } + + pub fn pair(&self) -> (&K, &V) { + (self.k, self.v) + } + + pub fn pair_mut(&mut self) -> (&K, &mut V) { + (self.k, self.v) + } + + pub fn downgrade(self) -> Ref<'a, K, V, S> { + Ref::new(self.guard.downgrade(), self.k, self.v) + } +} + +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() + } +} + +// -- |