From 9918693037dce8aa4bb6f08741b6812923486c18 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 11:26:03 +0200 Subject: Merging upstream version 1.76.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/dashmap/src/arbitrary.rs | 13 ++++++ vendor/dashmap/src/iter.rs | 2 +- vendor/dashmap/src/lib.rs | 48 ++++++++++++++++++-- vendor/dashmap/src/mapref/entry.rs | 89 ++++++++++++++++++++++++++++++++++++++ vendor/dashmap/src/mapref/one.rs | 14 ++++++ vendor/dashmap/src/rayon/map.rs | 2 +- vendor/dashmap/src/read_only.rs | 28 ++++++++++++ vendor/dashmap/src/serde.rs | 59 ++++++++++++++++++++++++- vendor/dashmap/src/set.rs | 2 +- 9 files changed, 250 insertions(+), 7 deletions(-) create mode 100644 vendor/dashmap/src/arbitrary.rs (limited to 'vendor/dashmap/src') diff --git a/vendor/dashmap/src/arbitrary.rs b/vendor/dashmap/src/arbitrary.rs new file mode 100644 index 000000000..a760964bb --- /dev/null +++ b/vendor/dashmap/src/arbitrary.rs @@ -0,0 +1,13 @@ +use arbitrary::{Arbitrary, Unstructured}; +use core::hash::BuildHasher; + +impl<'a, K, V, S> Arbitrary<'a> for crate::DashMap +where + K: Eq + std::hash::Hash + Arbitrary<'a>, + V: Arbitrary<'a>, + S: Default + BuildHasher + Clone, +{ + fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { + u.arbitrary_iter()?.collect() + } +} diff --git a/vendor/dashmap/src/iter.rs b/vendor/dashmap/src/iter.rs index cc2f12ea8..ce50e7390 100644 --- a/vendor/dashmap/src/iter.rs +++ b/vendor/dashmap/src/iter.rs @@ -118,7 +118,7 @@ pub struct Iter<'a, K, V, S = RandomState, M = DashMap> { current: Option>, } -impl<'a, 'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter<'i, K, V, S> { +impl<'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter<'i, K, V, S> { fn clone(&self) -> Self { Iter::new(self.map) } diff --git a/vendor/dashmap/src/lib.rs b/vendor/dashmap/src/lib.rs index bf112d570..34e5d8ba3 100644 --- a/vendor/dashmap/src/lib.rs +++ b/vendor/dashmap/src/lib.rs @@ -1,5 +1,7 @@ #![allow(clippy::type_complexity)] +#[cfg(feature = "arbitrary")] +mod arbitrary; pub mod iter; pub mod iter_set; mod lock; @@ -268,7 +270,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { hasher: S, shard_amount: usize, ) -> Self { - assert!(shard_amount > 0); + assert!(shard_amount > 1); assert!(shard_amount.is_power_of_two()); let shift = util::ptr_size_bits() - ncb(shard_amount); @@ -318,11 +320,51 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { pub fn shards(&self) -> &[RwLock>] { &self.shards } + + /// Provides mutable access to the inner shards that store your data. + /// You should probably not use this unless you know what you are doing. + /// + /// Requires the `raw-api` feature to be enabled. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// use dashmap::SharedValue; + /// + /// let mut map = DashMap::::new(); + /// let shard_ind = map.determine_map(&42); + /// map.shards_mut()[shard_ind].get_mut().insert(42, SharedValue::new("forty two")); + /// assert_eq!(*map.get(&42).unwrap(), "forty two"); + /// ``` + pub fn shards_mut(&mut self) -> &mut [RwLock>] { + &mut self.shards + } + + /// Consumes this `DashMap` and returns the inner shards. + /// You should probably not use this unless you know what you are doing. + /// + /// Requires the `raw-api` feature to be enabled. + /// + /// See [`DashMap::shards()`] and [`DashMap::shards_mut()`] for more information. + pub fn into_shards(self) -> Box<[RwLock>]> { + self.shards + } } else { #[allow(dead_code)] pub(crate) fn shards(&self) -> &[RwLock>] { &self.shards } + + #[allow(dead_code)] + pub(crate) fn shards_mut(&mut self) -> &mut [RwLock>] { + &mut self.shards + } + + #[allow(dead_code)] + pub(crate) fn into_shards(self) -> Box<[RwLock>]> { + self.shards + } } } @@ -510,7 +552,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { self._iter_mut() } - /// Get a immutable reference to an entry in the map + /// Get an immutable reference to an entry in the map /// /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. /// @@ -1223,7 +1265,7 @@ where } } -impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for DashMap { +impl IntoIterator for DashMap { type Item = (K, V); type IntoIter = OwningIter; diff --git a/vendor/dashmap/src/mapref/entry.rs b/vendor/dashmap/src/mapref/entry.rs index 16a42ce77..e9e6b913a 100644 --- a/vendor/dashmap/src/mapref/entry.rs +++ b/vendor/dashmap/src/mapref/entry.rs @@ -82,6 +82,36 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> { Entry::Vacant(entry) => Ok(entry.insert(value()?)), } } + + /// Sets the value of the entry, and returns a reference to the inserted value. + pub fn insert(self, value: V) -> RefMut<'a, K, V, S> { + match self { + Entry::Occupied(mut entry) => { + entry.insert(value); + entry.into_ref() + } + Entry::Vacant(entry) => entry.insert(value), + } + } + + /// Sets the value of the entry, and returns an OccupiedEntry. + /// + /// If you are not interested in the occupied entry, + /// consider [`insert`] as it doesn't need to clone the key. + /// + /// [`insert`]: Entry::insert + pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S> + where + K: Clone, + { + match self { + Entry::Occupied(mut entry) => { + entry.insert(value); + entry + } + Entry::Vacant(entry) => entry.insert_entry(value), + } + } } pub struct VacantEntry<'a, K, V, S = RandomState> { @@ -117,6 +147,22 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> { } } + /// Sets the value of the entry with the VacantEntry’s key, and returns an OccupiedEntry. + pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, S> + where + K: Clone, + { + unsafe { + self.shard.insert(self.key.clone(), SharedValue::new(value)); + + let (k, v) = self.shard.get_key_value(&self.key).unwrap(); + + let kptr: *const K = k; + let vptr: *mut V = v.as_ptr(); + OccupiedEntry::new(self.shard, self.key, (kptr, vptr)) + } + } + pub fn into_key(self) -> K { self.key } @@ -187,3 +233,46 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> { (k, v.into_inner()) } } + +#[cfg(test)] +mod tests { + use crate::DashMap; + + use super::*; + + #[test] + fn test_insert_entry_into_vacant() { + let map: DashMap = DashMap::new(); + + let entry = map.entry(1); + + assert!(matches!(entry, Entry::Vacant(_))); + + let entry = entry.insert_entry(2); + + assert_eq!(*entry.get(), 2); + + drop(entry); + + assert_eq!(*map.get(&1).unwrap(), 2); + } + + #[test] + fn test_insert_entry_into_occupied() { + let map: DashMap = DashMap::new(); + + map.insert(1, 1000); + + let entry = map.entry(1); + + assert!(matches!(&entry, Entry::Occupied(entry) if *entry.get() == 1000)); + + let entry = entry.insert_entry(2); + + assert_eq!(*entry.get(), 2); + + drop(entry); + + assert_eq!(*map.get(&1).unwrap(), 2); + } +} diff --git a/vendor/dashmap/src/mapref/one.rs b/vendor/dashmap/src/mapref/one.rs index 835e45cad..fd3853096 100644 --- a/vendor/dashmap/src/mapref/one.rs +++ b/vendor/dashmap/src/mapref/one.rs @@ -241,6 +241,20 @@ impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRef<'a, K, V, T, S> } } +impl<'a, K: Eq + Hash, V, T: std::fmt::Display> std::fmt::Display for MappedRef<'a, K, V, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.value(), f) + } +} + +impl<'a, K: Eq + Hash, V, T: AsRef, TDeref: ?Sized> AsRef + for MappedRef<'a, K, V, T> +{ + fn as_ref(&self) -> &TDeref { + self.value().as_ref() + } +} + pub struct MappedRefMut<'a, K, V, T, S = RandomState> { _guard: RwLockWriteGuard<'a, HashMap>, k: *const K, diff --git a/vendor/dashmap/src/rayon/map.rs b/vendor/dashmap/src/rayon/map.rs index 4fc0c43aa..ab45e6179 100644 --- a/vendor/dashmap/src/rayon/map.rs +++ b/vendor/dashmap/src/rayon/map.rs @@ -173,7 +173,7 @@ where } } -impl<'a, K, V, S> DashMap +impl DashMap where K: Send + Sync + Eq + Hash, V: Send + Sync, diff --git a/vendor/dashmap/src/read_only.rs b/vendor/dashmap/src/read_only.rs index 14582245b..42ee44331 100644 --- a/vendor/dashmap/src/read_only.rs +++ b/vendor/dashmap/src/read_only.rs @@ -1,5 +1,7 @@ +use crate::lock::RwLock; use crate::t::Map; use crate::{DashMap, HashMap}; +use cfg_if::cfg_if; use core::borrow::Borrow; use core::fmt; use core::hash::{BuildHasher, Hash}; @@ -121,6 +123,32 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView .flat_map(|shard| shard.values()) .map(|v| v.get()) } + + cfg_if! { + if #[cfg(feature = "raw-api")] { + /// Allows you to peek at the inner shards that store your data. + /// You should probably not use this unless you know what you are doing. + /// + /// Requires the `raw-api` feature to be enabled. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let map = DashMap::<(), ()>::new().into_read_only(); + /// println!("Amount of shards: {}", map.shards().len()); + /// ``` + pub fn shards(&self) -> &[RwLock>] { + &self.map.shards + } + } else { + #[allow(dead_code)] + pub(crate) fn shards(&self) -> &[RwLock>] { + &self.map.shards + } + } + } } #[cfg(test)] diff --git a/vendor/dashmap/src/serde.rs b/vendor/dashmap/src/serde.rs index df4fd2e48..6abeb069b 100644 --- a/vendor/dashmap/src/serde.rs +++ b/vendor/dashmap/src/serde.rs @@ -1,4 +1,4 @@ -use crate::{DashMap, DashSet}; +use crate::{mapref, setref, DashMap, DashSet}; use core::fmt; use core::hash::{BuildHasher, Hash}; use core::marker::PhantomData; @@ -156,3 +156,60 @@ where seq.end() } } + +macro_rules! serialize_impl { + () => { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + std::ops::Deref::deref(self).serialize(serializer) + } + }; +} + +// Map +impl<'a, K: Eq + Hash, V: Serialize, S: BuildHasher> Serialize + for mapref::multiple::RefMulti<'a, K, V, S> +{ + serialize_impl! {} +} + +impl<'a, K: Eq + Hash, V: Serialize, S: BuildHasher> Serialize + for mapref::multiple::RefMutMulti<'a, K, V, S> +{ + serialize_impl! {} +} + +impl<'a, K: Eq + Hash, V: Serialize, S: BuildHasher> Serialize for mapref::one::Ref<'a, K, V, S> { + serialize_impl! {} +} + +impl<'a, K: Eq + Hash, V: Serialize, S: BuildHasher> Serialize + for mapref::one::RefMut<'a, K, V, S> +{ + serialize_impl! {} +} + +impl<'a, K: Eq + Hash, V, T: Serialize, S: BuildHasher> Serialize + for mapref::one::MappedRef<'a, K, V, T, S> +{ + serialize_impl! {} +} + +impl<'a, K: Eq + Hash, V, T: Serialize, S: BuildHasher> Serialize + for mapref::one::MappedRefMut<'a, K, V, T, S> +{ + serialize_impl! {} +} + +// Set +impl<'a, V: Hash + Eq + Serialize, S: BuildHasher> Serialize + for setref::multiple::RefMulti<'a, V, S> +{ + serialize_impl! {} +} + +impl<'a, V: Hash + Eq + Serialize, S: BuildHasher> Serialize for setref::one::Ref<'a, V, S> { + serialize_impl! {} +} diff --git a/vendor/dashmap/src/set.rs b/vendor/dashmap/src/set.rs index 12445a994..1a5617706 100644 --- a/vendor/dashmap/src/set.rs +++ b/vendor/dashmap/src/set.rs @@ -385,7 +385,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { } } -impl<'a, K: Eq + Hash, S: BuildHasher + Clone> IntoIterator for DashSet { +impl IntoIterator for DashSet { type Item = K; type IntoIter = OwningIter; -- cgit v1.2.3