From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/dashmap/src/lib.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'vendor/dashmap/src/lib.rs') diff --git a/vendor/dashmap/src/lib.rs b/vendor/dashmap/src/lib.rs index 627b51381..bf112d570 100644 --- a/vendor/dashmap/src/lib.rs +++ b/vendor/dashmap/src/lib.rs @@ -16,6 +16,7 @@ mod util; #[cfg(feature = "rayon")] pub mod rayon { pub mod map; + pub mod read_only; pub mod set; } @@ -35,6 +36,7 @@ use iter::{Iter, IterMut, OwningIter}; use mapref::entry::{Entry, OccupiedEntry, VacantEntry}; use mapref::multiple::RefMulti; use mapref::one::{Ref, RefMut}; +use once_cell::sync::OnceCell; pub use read_only::ReadOnlyView; pub use set::DashSet; use std::collections::hash_map::RandomState; @@ -51,8 +53,19 @@ cfg_if! { pub(crate) type HashMap = hashbrown::HashMap, S>; +// Temporary reimplementation of [`std::collections::TryReserveError`] +// util [`std::collections::TryReserveError`] stabilises. +// We cannot easily create `std::collections` error type from `hashbrown` error type +// without access to `TryReserveError::kind` method. +#[non_exhaustive] +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct TryReserveError {} + fn default_shard_amount() -> usize { - (std::thread::available_parallelism().map_or(1, usize::from) * 4).next_power_of_two() + static DEFAULT_SHARD_AMOUNT: OnceCell = OnceCell::new(); + *DEFAULT_SHARD_AMOUNT.get_or_init(|| { + (std::thread::available_parallelism().map_or(1, usize::from) * 4).next_power_of_two() + }) } fn ncb(shard_amount: usize) -> usize { @@ -65,7 +78,7 @@ fn ncb(shard_amount: usize) -> usize { /// with some slight changes to handle concurrency. /// /// DashMap tries to be very simple to use and to be a direct replacement for `RwLock>`. -/// To accomplish these all methods take `&self` instead modifying methods taking `&mut self`. +/// To accomplish this, all methods take `&self` instead of modifying methods taking `&mut self`. /// This allows you to put a DashMap in an `Arc` and share it between threads while being able to modify it. /// /// Documentation mentioning locking behaviour acts in the reference frame of the calling thread. @@ -216,7 +229,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// Creates a new DashMap with a specified hasher and shard amount /// - /// shard_amount should greater than 0 and be a power of two. + /// shard_amount should be greater than 0 and a power of two. /// If a shard_amount which is not a power of two is provided, the function will panic. /// /// # Examples @@ -797,6 +810,24 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { pub fn try_entry(&'a self, key: K) -> Option> { self._try_entry(key) } + + /// Advanced entry API that tries to mimic `std::collections::HashMap::try_reserve`. + /// Tries to reserve capacity for at least `shard * additional` + /// and may reserve more space to avoid frequent reallocations. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error is returned. + // TODO: return std::collections::TryReserveError once std::collections::TryReserveErrorKind stabilises. + pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { + for shard in self.shards.iter() { + shard + .write() + .try_reserve(additional) + .map_err(|_| TryReserveError {})?; + } + Ok(()) + } } impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> @@ -1367,4 +1398,26 @@ mod tests { assert!(result2.is_locked()); } } + + #[test] + fn test_try_reserve() { + let mut map: DashMap = DashMap::new(); + // DashMap is empty and doesn't allocate memory + assert_eq!(map.capacity(), 0); + + map.try_reserve(10).unwrap(); + + // And now map can hold at least 10 elements + assert!(map.capacity() >= 10); + } + + #[test] + fn test_try_reserve_errors() { + let mut map: DashMap = DashMap::new(); + + match map.try_reserve(usize::MAX) { + Err(_) => {} + _ => panic!("should have raised CapacityOverflow error"), + } + } } -- cgit v1.2.3