From 0830082e04f0f213d6d68ddd558b4b13299fa981 Mon Sep 17 00:00:00 2001 From: Michael Krasnitski Date: Tue, 30 Dec 2025 17:33:32 -0500 Subject: [PATCH] Relax where-bounds on struct definitions and impl-blocks where possible This greatly reduces the number of `Eq + Hash` bounds peppered throughout the library and removes the `Clone` requirement on the choice of hasher, bringing the API closer in line with that of `std::collections::HashMap`. --- src/arbitrary.rs | 6 +- src/iter.rs | 19 +- src/iter_set.rs | 9 +- src/lib.rs | 453 +++++++++++++++++++++------------------- src/mapref/entry.rs | 7 +- src/mapref/entry_ref.rs | 12 +- src/mapref/multiple.rs | 11 +- src/mapref/one.rs | 79 ++++--- src/rayon/map.rs | 24 +-- src/rayon/read_only.rs | 9 +- src/rayon/set.rs | 18 +- src/read_only.rs | 97 +++++---- src/serde.rs | 46 ++-- src/set.rs | 237 +++++++++++---------- src/setref/multiple.rs | 5 +- src/setref/one.rs | 5 +- 16 files changed, 541 insertions(+), 496 deletions(-) diff --git a/src/arbitrary.rs b/src/arbitrary.rs index a760964b..66469446 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -1,11 +1,11 @@ use arbitrary::{Arbitrary, Unstructured}; -use core::hash::BuildHasher; +use core::hash::{BuildHasher, Hash}; impl<'a, K, V, S> Arbitrary<'a> for crate::DashMap where - K: Eq + std::hash::Hash + Arbitrary<'a>, + K: Eq + Hash + Arbitrary<'a>, V: Arbitrary<'a>, - S: Default + BuildHasher + Clone, + S: Default + BuildHasher, { fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { u.arbitrary_iter()?.collect() diff --git a/src/iter.rs b/src/iter.rs index 0c7ddbbd..d09ab082 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -4,7 +4,6 @@ use hashbrown::hash_table; use super::mapref::multiple::{RefMulti, RefMutMulti}; use crate::lock::{RwLock, RwLockReadGuardDetached, RwLockWriteGuardDetached}; use crate::{DashMap, HashMap}; -use core::hash::Hash; use std::sync::Arc; /// Iterator over a DashMap yielding key value pairs. @@ -25,7 +24,7 @@ pub struct OwningIter { current: Option>, } -impl OwningIter { +impl OwningIter { pub(crate) fn new(map: DashMap) -> Self { Self { shards: map.shards.into_vec().into_iter(), @@ -36,7 +35,7 @@ impl OwningIter { type GuardOwningIter = hash_table::IntoIter<(K, V)>; -impl Iterator for OwningIter { +impl Iterator for OwningIter { type Item = (K, V); fn next(&mut self) -> Option { @@ -79,7 +78,11 @@ pub struct Iter<'a, K, V> { current: Option>, } -impl<'i, K: Clone + Hash + Eq, V: Clone> Clone for Iter<'i, K, V> { +impl<'a, K, V> Clone for Iter<'a, K, V> +where + K: Clone, + V: Clone, +{ fn clone(&self) -> Self { Iter { shards: self.shards.clone(), @@ -88,7 +91,7 @@ impl<'i, K: Clone + Hash + Eq, V: Clone> Clone for Iter<'i, K, V> { } } -impl<'a, K: Eq + Hash + 'a, V: 'a> Iter<'a, K, V> { +impl<'a, K, V> Iter<'a, K, V> { pub(crate) fn new(map: &'a DashMap) -> Self { Self { shards: map.shards.iter(), @@ -97,7 +100,7 @@ impl<'a, K: Eq + Hash + 'a, V: 'a> Iter<'a, K, V> { } } -impl<'a, K: Eq + Hash + 'a, V: 'a> Iterator for Iter<'a, K, V> { +impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = RefMulti<'a, K, V>; fn next(&mut self) -> Option { @@ -138,7 +141,7 @@ pub struct IterMut<'a, K, V> { current: Option>, } -impl<'a, K: Eq + Hash + 'a, V: 'a> IterMut<'a, K, V> { +impl<'a, K, V> IterMut<'a, K, V> { pub(crate) fn new(map: &'a DashMap) -> Self { Self { shards: map.shards.iter(), @@ -147,7 +150,7 @@ impl<'a, K: Eq + Hash + 'a, V: 'a> IterMut<'a, K, V> { } } -impl<'a, K: Eq + Hash + 'a, V: 'a> Iterator for IterMut<'a, K, V> { +impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = RefMutMulti<'a, K, V>; fn next(&mut self) -> Option { diff --git a/src/iter_set.rs b/src/iter_set.rs index 0b90ec65..4439a529 100644 --- a/src/iter_set.rs +++ b/src/iter_set.rs @@ -1,17 +1,16 @@ use crate::setref::multiple::RefMulti; -use core::hash::Hash; pub struct OwningIter { inner: crate::iter::OwningIter, } -impl OwningIter { +impl OwningIter { pub(crate) fn new(inner: crate::iter::OwningIter) -> Self { Self { inner } } } -impl Iterator for OwningIter { +impl Iterator for OwningIter { type Item = K; fn next(&mut self) -> Option { @@ -23,13 +22,13 @@ pub struct Iter<'a, K> { inner: crate::iter::Iter<'a, K, ()>, } -impl<'a, K: Eq + Hash + 'a> Iter<'a, K> { +impl<'a, K> Iter<'a, K> { pub(crate) fn new(inner: crate::iter::Iter<'a, K, ()>) -> Self { Self { inner } } } -impl<'a, K: Eq + Hash + 'a> Iterator for Iter<'a, K> { +impl<'a, K> Iterator for Iter<'a, K> { type Item = RefMulti<'a, K>; fn next(&mut self) -> Option { diff --git a/src/lib.rs b/src/lib.rs index 2a9c6206..e26d9483 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ use crate::mapref::entry_ref::OccupiedEntryRef; use crate::mapref::entry_ref::VacantEntryRef; use cfg_if::cfg_if; -use core::fmt; +use core::fmt::{self, Debug}; use core::hash::{BuildHasher, Hash, Hasher}; use core::iter::FromIterator; use core::ops::{BitAnd, BitOr, Shl, Shr, Sub}; @@ -88,7 +88,12 @@ pub struct DashMap { hasher: S, } -impl Clone for DashMap { +impl Clone for DashMap +where + K: Clone, + V: Clone, + S: Clone, +{ fn clone(&self) -> Self { fn clone_rwlock(lock: &CachePadded>) -> CachePadded> { CachePadded::new(RwLock::new(lock.read().clone())) @@ -102,17 +107,13 @@ impl Clone for DashMap { } } -impl Default for DashMap -where - K: Eq + Hash, - S: Default + BuildHasher + Clone, -{ +impl Default for DashMap { fn default() -> Self { Self::with_hasher(Default::default()) } } -impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap { +impl DashMap { /// Creates a new DashMap with a capacity of 0. /// /// # Examples @@ -183,7 +184,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap { } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { +impl DashMap { /// Wraps this `DashMap` into a read-only view. This view allows to obtain raw references to the stored values. pub fn into_read_only(self) -> ReadOnlyView { ReadOnlyView::new(self) @@ -285,18 +286,141 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { } } - /// Hash a given item to produce a usize. - /// Uses the provided or default HashBuilder. - pub fn hash_usize(&self, item: &T) -> usize { - self.hash_u64(item) as usize + /// Returns how many key-value pairs the map can store without reallocating. + /// + /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. + pub fn capacity(&self) -> usize { + self.shards.iter().map(|s| s.read().capacity()).sum() } - fn hash_u64(&self, item: &T) -> u64 { - let mut hasher = self.hasher.build_hasher(); + /// Fetches the total number of key-value pairs stored in the map. + /// + /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let people = DashMap::new(); + /// people.insert("Albin", 15); + /// people.insert("Jones", 22); + /// people.insert("Charlie", 27); + /// assert_eq!(people.len(), 3); + /// ``` + pub fn len(&self) -> usize { + self.shards.iter().map(|s| s.read().len()).sum() + } - item.hash(&mut hasher); + /// Checks if the map is empty or not. + /// + /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let map = DashMap::<(), ()>::new(); + /// assert!(map.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.len() == 0 + } - hasher.finish() + /// Creates an iterator over a DashMap yielding immutable references. + /// + /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let words = DashMap::new(); + /// words.insert("hello", "world"); + /// assert_eq!(words.iter().count(), 1); + /// ``` + pub fn iter(&self) -> Iter<'_, K, V> { + Iter::new(self) + } + + /// Iterator over a DashMap yielding mutable references. + /// + /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let map = DashMap::new(); + /// map.insert("Johnny", 21); + /// map.iter_mut().for_each(|mut r| *r += 1); + /// assert_eq!(*map.get("Johnny").unwrap(), 22); + /// ``` + pub fn iter_mut(&self) -> IterMut<'_, K, V> { + IterMut::new(self) + } + + /// Retain elements that whose predicates return true + /// and discard elements whose predicates return false. + /// + /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let people = DashMap::new(); + /// people.insert("Albin", 15); + /// people.insert("Jones", 22); + /// people.insert("Charlie", 27); + /// people.retain(|_, v| *v > 20); + /// assert_eq!(people.len(), 2); + /// ``` + pub fn retain(&self, mut f: impl FnMut(&K, &mut V) -> bool) { + self.shards.iter().for_each(|s| { + s.write().retain(|(k, v)| f(k, v)); + }); + } + + /// Removes all key-value pairs in the map. + /// + /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashMap; + /// + /// let stats = DashMap::new(); + /// stats.insert("Goals", 4); + /// assert!(!stats.is_empty()); + /// stats.clear(); + /// assert!(stats.is_empty()); + /// ``` + pub fn clear(&self) { + self.retain(|_, _| false) + } + + /// Returns a reference to the map's [`BuildHasher`]. + /// + /// # Examples + /// + /// ```rust + /// use dashmap::DashMap; + /// use std::collections::hash_map::RandomState; + /// + /// let hasher = RandomState::new(); + /// let map: DashMap = DashMap::new(); + /// let hasher: &RandomState = map.hasher(); + /// ``` + /// + /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html + pub fn hasher(&self) -> &S { + &self.hasher } cfg_if! { @@ -372,6 +496,26 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { } } } +} + +impl DashMap +where + K: Eq + Hash, + S: BuildHasher, +{ + /// Hash a given item to produce a usize. + /// Uses the provided or default HashBuilder. + pub fn hash_usize(&self, item: &T) -> usize { + self.hash_u64(item) as usize + } + + fn hash_u64(&self, item: &T) -> u64 { + let mut hasher = self.hasher.build_hasher(); + + item.hash(&mut hasher); + + hasher.finish() + } cfg_if! { if #[cfg(feature = "raw-api")] { @@ -461,24 +605,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { } } - /// Returns a reference to the map's [`BuildHasher`]. - /// - /// # Examples - /// - /// ```rust - /// use dashmap::DashMap; - /// use std::collections::hash_map::RandomState; - /// - /// let hasher = RandomState::new(); - /// let map: DashMap = DashMap::new(); - /// let hasher: &RandomState = map.hasher(); - /// ``` - /// - /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html - pub fn hasher(&self) -> &S { - &self.hasher - } - /// Inserts a key and a value into the map. Returns the old value associated with the key if there was one. /// Does not update the key if it was already present. /// @@ -551,41 +677,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { self._remove_if_mut(key, f) } - /// Creates an iterator over a DashMap yielding immutable references. - /// - /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashMap; - /// - /// let words = DashMap::new(); - /// words.insert("hello", "world"); - /// assert_eq!(words.iter().count(), 1); - /// ``` - pub fn iter(&'a self) -> Iter<'a, K, V> { - self._iter() - } - - /// Iterator over a DashMap yielding mutable references. - /// - /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashMap; - /// - /// let map = DashMap::new(); - /// map.insert("Johnny", 21); - /// map.iter_mut().for_each(|mut r| *r += 1); - /// assert_eq!(*map.get("Johnny").unwrap(), 22); - /// ``` - pub fn iter_mut(&'a self) -> IterMut<'a, K, V> { - self._iter_mut() - } - /// Get an immutable reference to an entry in the map /// /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. @@ -599,7 +690,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// youtubers.insert("Bosnian Bill", 457000); /// assert_eq!(*youtubers.get("Bosnian Bill").unwrap(), 457000); /// ``` - pub fn get(&'a self, key: &Q) -> Option> + pub fn get(&self, key: &Q) -> Option> where Q: Hash + Equivalent + ?Sized, { @@ -620,7 +711,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// *class.get_mut("Albin").unwrap() -= 1; /// assert_eq!(*class.get("Albin").unwrap(), 14); /// ``` - pub fn get_mut(&'a self, key: &Q) -> Option> + pub fn get_mut(&self, key: &Q) -> Option> where Q: Hash + Equivalent + ?Sized, { @@ -646,7 +737,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// let result2 = map.try_get("Johnny"); /// assert!(result2.is_locked()); /// ``` - pub fn try_get(&'a self, key: &Q) -> TryResult> + pub fn try_get(&self, key: &Q) -> TryResult> where Q: Hash + Equivalent + ?Sized, { @@ -673,7 +764,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// let result2 = map.try_get_mut("Johnny"); /// assert!(result2.is_locked()); /// ``` - pub fn try_get_mut(&'a self, key: &Q) -> TryResult> + pub fn try_get_mut(&self, key: &Q) -> TryResult> where Q: Hash + Equivalent + ?Sized, { @@ -700,88 +791,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { self._shrink_to_fit(); } - /// Retain elements that whose predicates return true - /// and discard elements whose predicates return false. - /// - /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashMap; - /// - /// let people = DashMap::new(); - /// people.insert("Albin", 15); - /// people.insert("Jones", 22); - /// people.insert("Charlie", 27); - /// people.retain(|_, v| *v > 20); - /// assert_eq!(people.len(), 2); - /// ``` - pub fn retain(&self, f: impl FnMut(&K, &mut V) -> bool) { - self._retain(f); - } - - /// Fetches the total number of key-value pairs stored in the map. - /// - /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashMap; - /// - /// let people = DashMap::new(); - /// people.insert("Albin", 15); - /// people.insert("Jones", 22); - /// people.insert("Charlie", 27); - /// assert_eq!(people.len(), 3); - /// ``` - pub fn len(&self) -> usize { - self._len() - } - - /// Checks if the map is empty or not. - /// - /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashMap; - /// - /// let map = DashMap::<(), ()>::new(); - /// assert!(map.is_empty()); - /// ``` - pub fn is_empty(&self) -> bool { - self._is_empty() - } - - /// Removes all key-value pairs in the map. - /// - /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashMap; - /// - /// let stats = DashMap::new(); - /// stats.insert("Goals", 4); - /// assert!(!stats.is_empty()); - /// stats.clear(); - /// assert!(stats.is_empty()); - /// ``` - pub fn clear(&self) { - self._clear(); - } - - /// Returns how many key-value pairs the map can store without reallocating. - /// - /// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map. - pub fn capacity(&self) -> usize { - self._capacity() - } - /// Modify a specific value according to a function. /// /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. @@ -881,7 +890,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// See the documentation on `dashmap::mapref::entry` for more details. /// /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. - pub fn entry(&'a self, key: K) -> Entry<'a, K, V> { + pub fn entry(&self, key: K) -> Entry<'_, K, V> { self._entry(key) } @@ -889,7 +898,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// See the documentation on `dashmap::mapref::entry` for more details. /// /// Returns None if the shard is currently locked. - pub fn try_entry(&'a self, key: K) -> Option> { + pub fn try_entry(&self, key: K) -> Option> { self._try_entry(key) } @@ -897,7 +906,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// See the documentation on `dashmap::mapref::entry_ref` for more details. /// /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. - pub fn entry_ref<'q, Q>(&'a self, key: &'q Q) -> EntryRef<'a, 'q, K, Q, V> + pub fn entry_ref<'q, Q>(&self, key: &'q Q) -> EntryRef<'_, 'q, K, Q, V> where Q: Hash + Equivalent, { @@ -927,7 +936,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap { +impl DashMap +where + K: Eq + Hash, + S: BuildHasher, +{ fn _insert(&self, key: K, value: V) -> Option { match self.entry(key) { Entry::Occupied(mut o) => Some(o.insert(value)), @@ -1002,15 +1015,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _iter(&'a self) -> Iter<'a, K, V> { - Iter::new(self) - } - - fn _iter_mut(&'a self) -> IterMut<'a, K, V> { - IterMut::new(self) - } - - fn _get(&'a self, key: &Q) -> Option> + fn _get(&self, key: &Q) -> Option> where Q: Hash + Equivalent + ?Sized, { @@ -1029,7 +1034,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _get_mut(&'a self, key: &Q) -> Option> + fn _get_mut(&self, key: &Q) -> Option> where Q: Hash + Equivalent + ?Sized, { @@ -1048,7 +1053,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _try_get(&'a self, key: &Q) -> TryResult> + fn _try_get(&self, key: &Q) -> TryResult> where Q: Hash + Equivalent + ?Sized, { @@ -1070,7 +1075,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _try_get_mut(&'a self, key: &Q) -> TryResult> + fn _try_get_mut(&self, key: &Q) -> TryResult> where Q: Hash + Equivalent + ?Sized, { @@ -1104,20 +1109,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap }); } - fn _retain(&self, mut f: impl FnMut(&K, &mut V) -> bool) { - self.shards.iter().for_each(|s| { - s.write().retain(|(k, v)| f(k, v)); - }); - } - - fn _len(&self) -> usize { - self.shards.iter().map(|s| s.read().len()).sum() - } - - fn _capacity(&self) -> usize { - self.shards.iter().map(|s| s.read().capacity()).sum() - } - fn _alter(&self, key: &Q, f: impl FnOnce(&K, V) -> V) where Q: Hash + Equivalent + ?Sized, @@ -1142,7 +1133,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap }) } - fn _entry(&'a self, key: K) -> Entry<'a, K, V> { + fn _entry(&self, key: K) -> Entry<'_, K, V> { let hash = self.hash_u64(&key); let idx = self.determine_shard(hash as usize); @@ -1167,7 +1158,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _try_entry(&'a self, key: K) -> Option> { + fn _try_entry(&self, key: K) -> Option> { let hash = self.hash_u64(&key); let idx = self.determine_shard(hash as usize); @@ -1197,7 +1188,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _entry_ref<'q, Q>(&'a self, key: &'q Q) -> EntryRef<'a, 'q, K, Q, V> + fn _entry_ref<'q, Q>(&self, key: &'q Q) -> EntryRef<'_, 'q, K, Q, V> where Q: Hash + Equivalent, { @@ -1227,7 +1218,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _try_entry_ref<'q, Q>(&'a self, key: &'q Q) -> Option> + fn _try_entry_ref<'q, Q>(&self, key: &'q Q) -> Option> where Q: Hash + Equivalent, { @@ -1260,24 +1251,18 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> DashMap } } - fn _clear(&self) { - self._retain(|_, _| false) - } - - fn _contains_key(&'a self, key: &Q) -> bool + fn _contains_key(&self, key: &Q) -> bool where Q: Hash + Equivalent + ?Sized, { self._get(key).is_some() } - - fn _is_empty(&self) -> bool { - self._len() == 0 - } } -impl fmt::Debug - for DashMap +impl Debug for DashMap +where + K: Debug, + V: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut pmap = f.debug_map(); @@ -1292,7 +1277,11 @@ impl fmt::Debu } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> Shl<(K, V)> for &'a DashMap { +impl Shl<(K, V)> for &DashMap +where + K: Eq + Hash, + S: BuildHasher, +{ type Output = Option; fn shl(self, pair: (K, V)) -> Self::Output { @@ -1300,9 +1289,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> Shl<(K, V)> for &'a D } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Shr<&Q> for &'a DashMap +impl<'a, K, V, S, Q> Shr<&Q> for &'a DashMap where + K: Eq + Hash, Q: Hash + Equivalent + ?Sized, + S: BuildHasher, { type Output = Ref<'a, K, V>; @@ -1311,9 +1302,11 @@ where } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitOr<&Q> for &'a DashMap +impl<'a, K, V, S, Q> BitOr<&Q> for &'a DashMap where + K: Eq + Hash, Q: Hash + Equivalent + ?Sized, + S: BuildHasher, { type Output = RefMut<'a, K, V>; @@ -1322,9 +1315,11 @@ where } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> Sub<&Q> for &'a DashMap +impl Sub<&Q> for &DashMap where + K: Eq + Hash, Q: Hash + Equivalent + ?Sized, + S: BuildHasher, { type Output = Option<(K, V)>; @@ -1333,9 +1328,11 @@ where } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone, Q> BitAnd<&Q> for &'a DashMap +impl BitAnd<&Q> for &DashMap where + K: Eq + Hash, Q: Hash + Equivalent + ?Sized, + S: BuildHasher, { type Output = bool; @@ -1344,8 +1341,11 @@ where } } -impl<'a, K: 'a + Eq + Hash, V: 'a + PartialEq, S: BuildHasher + Clone> PartialEq - for DashMap +impl PartialEq for DashMap +where + K: Eq + Hash, + V: PartialEq, + S: BuildHasher, { fn eq(&self, other: &Self) -> bool { self.len() == other.len() @@ -1357,9 +1357,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a + PartialEq, S: BuildHasher + Clone> PartialEq } } -impl<'a, K: 'a + Eq + Hash, V: 'a + Eq, S: BuildHasher + Clone> Eq for DashMap {} +impl Eq for DashMap {} -impl IntoIterator for DashMap { +impl IntoIterator for DashMap { type Item = (K, V); type IntoIter = OwningIter; @@ -1369,7 +1369,7 @@ impl IntoIterator for DashMap } } -impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap { +impl<'a, K, V, S> IntoIterator for &'a DashMap { type Item = RefMulti<'a, K, V>; type IntoIter = Iter<'a, K, V>; @@ -1379,16 +1379,30 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap Extend<(K, V)> for DashMap { - fn extend>(&mut self, intoiter: I) { - for pair in intoiter.into_iter() { - self.insert(pair.0, pair.1); +impl Extend<(K, V)> for DashMap +where + K: Eq + Hash, + S: BuildHasher, +{ + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + for (k, v) in iter { + self.insert(k, v); } } } -impl FromIterator<(K, V)> for DashMap { - fn from_iter>(intoiter: I) -> Self { +impl FromIterator<(K, V)> for DashMap +where + K: Eq + Hash, + S: BuildHasher + Default, +{ + fn from_iter(intoiter: I) -> Self + where + I: IntoIterator, + { let mut map = DashMap::default(); map.extend(intoiter); @@ -1400,9 +1414,9 @@ impl FromIterator<(K, V)> for #[cfg(feature = "typesize")] impl typesize::TypeSize for DashMap where - K: typesize::TypeSize + Eq + Hash, + K: typesize::TypeSize, V: typesize::TypeSize, - S: typesize::TypeSize + Clone + BuildHasher, + S: typesize::TypeSize, { fn extra_size(&self) -> usize { let shards_extra_size: usize = self @@ -1492,7 +1506,6 @@ mod tests { #[test] fn test_more_complex_values() { #[derive(Hash, PartialEq, Debug, Clone)] - struct T0 { s: String, u: u8, diff --git a/src/mapref/entry.rs b/src/mapref/entry.rs index 6edf5427..2c0948c1 100644 --- a/src/mapref/entry.rs +++ b/src/mapref/entry.rs @@ -2,7 +2,6 @@ use hashbrown::hash_table; use super::one::RefMut; use crate::lock::RwLockWriteGuardDetached; -use core::hash::Hash; use core::mem; pub enum Entry<'a, K, V> { @@ -10,7 +9,7 @@ pub enum Entry<'a, K, V> { Vacant(VacantEntry<'a, K, V>), } -impl<'a, K: Eq + Hash, V> Entry<'a, K, V> { +impl<'a, K, V> Entry<'a, K, V> { /// Apply a function to the stored value if it exists. pub fn and_modify(self, f: impl FnOnce(&mut V)) -> Self { match self { @@ -117,7 +116,7 @@ pub struct VacantEntry<'a, K, V> { entry: hash_table::VacantEntry<'a, (K, V)>, } -impl<'a, K: Eq + Hash, V> VacantEntry<'a, K, V> { +impl<'a, K, V> VacantEntry<'a, K, V> { pub(crate) fn new( shard: RwLockWriteGuardDetached<'a>, key: K, @@ -158,7 +157,7 @@ pub struct OccupiedEntry<'a, K, V> { key: K, } -impl<'a, K: Eq + Hash, V> OccupiedEntry<'a, K, V> { +impl<'a, K, V> OccupiedEntry<'a, K, V> { pub(crate) fn new( shard: RwLockWriteGuardDetached<'a>, key: K, diff --git a/src/mapref/entry_ref.rs b/src/mapref/entry_ref.rs index da8e7c29..8e6c1b77 100644 --- a/src/mapref/entry_ref.rs +++ b/src/mapref/entry_ref.rs @@ -2,7 +2,6 @@ use hashbrown::hash_table; use super::one::RefMut; use crate::lock::RwLockWriteGuardDetached; -use core::hash::Hash; use std::mem; /// Entry with a borrowed key. @@ -11,7 +10,7 @@ pub enum EntryRef<'a, 'q, K, Q, V> { Vacant(VacantEntryRef<'a, 'q, K, Q, V>), } -impl<'a, 'q, K: Eq + Hash, Q, V> EntryRef<'a, 'q, K, Q, V> { +impl<'a, 'q, K, Q, V> EntryRef<'a, 'q, K, Q, V> { /// Apply a function to the stored value if it exists. pub fn and_modify(self, f: impl FnOnce(&mut V)) -> Self { match self { @@ -26,7 +25,10 @@ impl<'a, 'q, K: Eq + Hash, Q, V> EntryRef<'a, 'q, K, Q, V> { } } -impl<'a, 'q, K: Eq + Hash + From<&'q Q>, Q, V> EntryRef<'a, 'q, K, Q, V> { +impl<'a, 'q, K, Q, V> EntryRef<'a, 'q, K, Q, V> +where + K: From<&'q Q>, +{ /// Get the key of the entry. pub fn key(&self) -> &Q { match *self { @@ -120,7 +122,7 @@ pub struct VacantEntryRef<'a, 'q, K, Q, V> { key: &'q Q, } -impl<'a, 'q, K: Eq + Hash, Q, V> VacantEntryRef<'a, 'q, K, Q, V> { +impl<'a, 'q, K, Q, V> VacantEntryRef<'a, 'q, K, Q, V> { pub(crate) fn new( shard: RwLockWriteGuardDetached<'a>, key: &'q Q, @@ -168,7 +170,7 @@ pub struct OccupiedEntryRef<'a, 'q, K, Q, V> { key: &'q Q, } -impl<'a, 'q, K: Eq + Hash, Q, V> OccupiedEntryRef<'a, 'q, K, Q, V> { +impl<'a, 'q, K, Q, V> OccupiedEntryRef<'a, 'q, K, Q, V> { pub(crate) fn new( shard: RwLockWriteGuardDetached<'a>, key: &'q Q, diff --git a/src/mapref/multiple.rs b/src/mapref/multiple.rs index 053eb18b..3f6ee0d0 100644 --- a/src/mapref/multiple.rs +++ b/src/mapref/multiple.rs @@ -1,5 +1,4 @@ use crate::lock::{RwLockReadGuardDetached, RwLockWriteGuardDetached}; -use core::hash::Hash; use core::ops::{Deref, DerefMut}; use std::sync::Arc; @@ -9,7 +8,7 @@ pub struct RefMulti<'a, K, V> { v: &'a V, } -impl<'a, K: Eq + Hash, V> RefMulti<'a, K, V> { +impl<'a, K, V> RefMulti<'a, K, V> { pub(crate) fn new(guard: Arc>, k: &'a K, v: &'a V) -> Self { Self { _guard: guard, @@ -31,7 +30,7 @@ impl<'a, K: Eq + Hash, V> RefMulti<'a, K, V> { } } -impl<'a, K: Eq + Hash, V> Deref for RefMulti<'a, K, V> { +impl<'a, K, V> Deref for RefMulti<'a, K, V> { type Target = V; fn deref(&self) -> &V { @@ -45,7 +44,7 @@ pub struct RefMutMulti<'a, K, V> { v: &'a mut V, } -impl<'a, K: Eq + Hash, V> RefMutMulti<'a, K, V> { +impl<'a, K, V> RefMutMulti<'a, K, V> { pub(crate) fn new(guard: Arc>, k: &'a K, v: &'a mut V) -> Self { Self { _guard: guard, @@ -75,7 +74,7 @@ impl<'a, K: Eq + Hash, V> RefMutMulti<'a, K, V> { } } -impl<'a, K: Eq + Hash, V> Deref for RefMutMulti<'a, K, V> { +impl<'a, K, V> Deref for RefMutMulti<'a, K, V> { type Target = V; fn deref(&self) -> &V { @@ -83,7 +82,7 @@ impl<'a, K: Eq + Hash, V> Deref for RefMutMulti<'a, K, V> { } } -impl<'a, K: Eq + Hash, V> DerefMut for RefMutMulti<'a, K, V> { +impl<'a, K, V> DerefMut for RefMutMulti<'a, K, V> { fn deref_mut(&mut self) -> &mut V { self.value_mut() } diff --git a/src/mapref/one.rs b/src/mapref/one.rs index faf47d9c..7ae23951 100644 --- a/src/mapref/one.rs +++ b/src/mapref/one.rs @@ -1,7 +1,6 @@ use crate::lock::{RwLockReadGuardDetached, RwLockWriteGuardDetached}; -use core::hash::Hash; +use core::fmt::{self, Debug, Display}; use core::ops::{Deref, DerefMut}; -use std::fmt::{Debug, Formatter}; pub struct Ref<'a, K, V> { _guard: RwLockReadGuardDetached<'a>, @@ -9,7 +8,7 @@ pub struct Ref<'a, K, V> { v: &'a V, } -impl<'a, K: Eq + Hash, V> Ref<'a, K, V> { +impl<'a, K, V> Ref<'a, K, V> { pub(crate) fn new(guard: RwLockReadGuardDetached<'a>, k: &'a K, v: &'a V) -> Self { Self { _guard: guard, @@ -57,8 +56,12 @@ impl<'a, K: Eq + Hash, V> Ref<'a, K, V> { } } -impl<'a, K: Eq + Hash + Debug, V: Debug> Debug for Ref<'a, K, V> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl<'a, K, V> Debug for Ref<'a, K, V> +where + K: Debug, + V: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Ref") .field("k", &self.k) .field("v", &self.v) @@ -66,7 +69,7 @@ impl<'a, K: Eq + Hash + Debug, V: Debug> Debug for Ref<'a, K, V> { } } -impl<'a, K: Eq + Hash, V> Deref for Ref<'a, K, V> { +impl<'a, K, V> Deref for Ref<'a, K, V> { type Target = V; fn deref(&self) -> &V { @@ -80,7 +83,7 @@ pub struct RefMut<'a, K, V> { v: &'a mut V, } -impl<'a, K: Eq + Hash, V> RefMut<'a, K, V> { +impl<'a, K, V> RefMut<'a, K, V> { pub(crate) fn new(guard: RwLockWriteGuardDetached<'a>, k: &'a K, v: &'a mut V) -> Self { Self { guard, k, v } } @@ -142,8 +145,12 @@ impl<'a, K: Eq + Hash, V> RefMut<'a, K, V> { } } -impl<'a, K: Eq + Hash + Debug, V: Debug> Debug for RefMut<'a, K, V> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl<'a, K, V> Debug for RefMut<'a, K, V> +where + K: Debug, + V: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RefMut") .field("k", &self.k) .field("v", &self.v) @@ -151,7 +158,7 @@ impl<'a, K: Eq + Hash + Debug, V: Debug> Debug for RefMut<'a, K, V> { } } -impl<'a, K: Eq + Hash, V> Deref for RefMut<'a, K, V> { +impl<'a, K, V> Deref for RefMut<'a, K, V> { type Target = V; fn deref(&self) -> &V { @@ -159,7 +166,7 @@ impl<'a, K: Eq + Hash, V> Deref for RefMut<'a, K, V> { } } -impl<'a, K: Eq + Hash, V> DerefMut for RefMut<'a, K, V> { +impl<'a, K, V> DerefMut for RefMut<'a, K, V> { fn deref_mut(&mut self) -> &mut V { self.value_mut() } @@ -171,7 +178,7 @@ pub struct MappedRef<'a, K, T: ?Sized> { v: &'a T, } -impl<'a, K: Eq + Hash, T: ?Sized> MappedRef<'a, K, T> { +impl<'a, K, T: ?Sized> MappedRef<'a, K, T> { pub fn key(&self) -> &K { self.pair().0 } @@ -212,8 +219,12 @@ impl<'a, K: Eq + Hash, T: ?Sized> MappedRef<'a, K, T> { } } -impl<'a, K: Eq + Hash + Debug, T: Debug + ?Sized> Debug for MappedRef<'a, K, T> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl<'a, K, T: ?Sized> Debug for MappedRef<'a, K, T> +where + K: Debug, + T: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MappedRef") .field("k", &self.k) .field("v", &self.v) @@ -221,7 +232,7 @@ impl<'a, K: Eq + Hash + Debug, T: Debug + ?Sized> Debug for MappedRef<'a, K, T> } } -impl<'a, K: Eq + Hash, T: ?Sized> Deref for MappedRef<'a, K, T> { +impl<'a, K, T: ?Sized> Deref for MappedRef<'a, K, T> { type Target = T; fn deref(&self) -> &T { @@ -229,16 +240,20 @@ impl<'a, K: Eq + Hash, T: ?Sized> Deref for MappedRef<'a, K, T> { } } -impl<'a, K: Eq + Hash, T: std::fmt::Display + ?Sized> std::fmt::Display for MappedRef<'a, K, T> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.value(), f) +impl<'a, K, T: ?Sized> Display for MappedRef<'a, K, T> +where + T: Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Display::fmt(self.value(), f) } } -impl<'a, K: Eq + Hash, T: ?Sized + AsRef, TDeref: ?Sized> AsRef - for MappedRef<'a, K, T> +impl<'a, K, T: ?Sized, U: ?Sized> AsRef for MappedRef<'a, K, T> +where + T: AsRef, { - fn as_ref(&self) -> &TDeref { + fn as_ref(&self) -> &U { self.value().as_ref() } } @@ -249,7 +264,7 @@ pub struct MappedRefMut<'a, K, T: ?Sized> { v: &'a mut T, } -impl<'a, K: Eq + Hash, T: ?Sized> MappedRefMut<'a, K, T> { +impl<'a, K, T: ?Sized> MappedRefMut<'a, K, T> { pub fn key(&self) -> &K { self.pair().0 } @@ -270,9 +285,9 @@ impl<'a, K: Eq + Hash, T: ?Sized> MappedRefMut<'a, K, T> { (self.k, self.v) } - pub fn map(self, f: F) -> MappedRefMut<'a, K, T2> + pub fn map(self, f: F) -> MappedRefMut<'a, K, U> where - F: FnOnce(&mut T) -> &mut T2, + F: FnOnce(&mut T) -> &mut U, { MappedRefMut { _guard: self._guard, @@ -281,9 +296,9 @@ impl<'a, K: Eq + Hash, T: ?Sized> MappedRefMut<'a, K, T> { } } - pub fn try_map(self, f: F) -> Result, Self> + pub fn try_map(self, f: F) -> Result, Self> where - F: FnOnce(&mut T) -> Option<&mut T2>, + F: FnOnce(&mut T) -> Option<&mut U>, { let v = match f(unsafe { &mut *(self.v as *mut _) }) { Some(v) => v, @@ -299,8 +314,12 @@ impl<'a, K: Eq + Hash, T: ?Sized> MappedRefMut<'a, K, T> { } } -impl<'a, K: Eq + Hash + Debug, T: Debug + ?Sized> Debug for MappedRefMut<'a, K, T> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +impl<'a, K, T: ?Sized> Debug for MappedRefMut<'a, K, T> +where + K: Debug, + T: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("MappedRefMut") .field("k", &self.k) .field("v", &self.v) @@ -308,7 +327,7 @@ impl<'a, K: Eq + Hash + Debug, T: Debug + ?Sized> Debug for MappedRefMut<'a, K, } } -impl<'a, K: Eq + Hash, T: ?Sized> Deref for MappedRefMut<'a, K, T> { +impl<'a, K, T: ?Sized> Deref for MappedRefMut<'a, K, T> { type Target = T; fn deref(&self) -> &T { @@ -316,7 +335,7 @@ impl<'a, K: Eq + Hash, T: ?Sized> Deref for MappedRefMut<'a, K, T> { } } -impl<'a, K: Eq + Hash, T: ?Sized> DerefMut for MappedRefMut<'a, K, T> { +impl<'a, K, T: ?Sized> DerefMut for MappedRefMut<'a, K, T> { fn deref_mut(&mut self) -> &mut T { self.value_mut() } diff --git a/src/rayon/map.rs b/src/rayon/map.rs index c90fbb3b..4e47bfa1 100644 --- a/src/rayon/map.rs +++ b/src/rayon/map.rs @@ -11,7 +11,7 @@ impl ParallelExtend<(K, V)> for DashMap where K: Send + Sync + Eq + Hash, V: Send + Sync, - S: Send + Sync + Clone + BuildHasher, + S: Send + Sync + BuildHasher, { fn par_extend(&mut self, par_iter: I) where @@ -27,7 +27,7 @@ impl ParallelExtend<(K, V)> for &'_ DashMap where K: Send + Sync + Eq + Hash, V: Send + Sync, - S: Send + Sync + Clone + BuildHasher, + S: Send + Sync + BuildHasher, { fn par_extend(&mut self, par_iter: I) where @@ -44,7 +44,7 @@ impl FromParallelIterator<(K, V)> for DashMap where K: Send + Sync + Eq + Hash, V: Send + Sync, - S: Send + Sync + Clone + Default + BuildHasher, + S: Send + Sync + BuildHasher + Default, { fn from_par_iter(par_iter: I) -> Self where @@ -64,9 +64,9 @@ where impl IntoParallelIterator for DashMap where - K: Send + Eq + Hash, + K: Send, V: Send, - S: Send + Clone + BuildHasher, + S: Send, { type Iter = OwningIter; type Item = (K, V); @@ -84,7 +84,7 @@ pub struct OwningIter { impl ParallelIterator for OwningIter where - K: Send + Eq + Hash, + K: Send, V: Send, { type Item = (K, V); @@ -103,9 +103,9 @@ where // This impl also enables `IntoParallelRefIterator::par_iter` impl<'a, K, V, S> IntoParallelIterator for &'a DashMap where - K: Send + Sync + Eq + Hash, + K: Send + Sync, V: Send + Sync, - S: Send + Sync + Clone + BuildHasher, + S: Send + Sync, { type Iter = Iter<'a, K, V>; type Item = RefMulti<'a, K, V>; @@ -123,7 +123,7 @@ pub struct Iter<'a, K, V> { impl<'a, K, V> ParallelIterator for Iter<'a, K, V> where - K: Send + Sync + Eq + Hash, + K: Send + Sync, V: Send + Sync, { type Item = RefMulti<'a, K, V>; @@ -152,7 +152,7 @@ where // This impl also enables `IntoParallelRefMutIterator::par_iter_mut` impl<'a, K, V> IntoParallelIterator for &'a mut DashMap where - K: Send + Sync + Eq + Hash, + K: Send + Sync, V: Send + Sync, { type Iter = IterMut<'a, K, V>; @@ -167,7 +167,7 @@ where impl DashMap where - K: Send + Sync + Eq + Hash, + K: Send + Sync, V: Send + Sync, { // Unlike `IntoParallelRefMutIterator::par_iter_mut`, we only _need_ `&self`. @@ -184,7 +184,7 @@ pub struct IterMut<'a, K, V> { impl<'a, K, V> ParallelIterator for IterMut<'a, K, V> where - K: Send + Sync + Eq + Hash, + K: Send + Sync, V: Send + Sync, { type Item = RefMutMulti<'a, K, V>; diff --git a/src/rayon/read_only.rs b/src/rayon/read_only.rs index d37bb875..2f514987 100644 --- a/src/rayon/read_only.rs +++ b/src/rayon/read_only.rs @@ -1,14 +1,13 @@ use crate::mapref::multiple::RefMulti; use crate::rayon::map::Iter; use crate::ReadOnlyView; -use core::hash::{BuildHasher, Hash}; use rayon::iter::IntoParallelIterator; impl IntoParallelIterator for ReadOnlyView where - K: Send + Eq + Hash, + K: Send, V: Send, - S: Send + Clone + BuildHasher, + S: Send, { type Iter = super::map::OwningIter; type Item = (K, V); @@ -23,9 +22,9 @@ where // This impl also enables `IntoParallelRefIterator::par_iter` impl<'a, K, V, S> IntoParallelIterator for &'a ReadOnlyView where - K: Send + Sync + Eq + Hash, + K: Send + Sync, V: Send + Sync, - S: Send + Sync + Clone + BuildHasher, + S: Send + Sync, { type Iter = Iter<'a, K, V>; type Item = RefMulti<'a, K, V>; diff --git a/src/rayon/set.rs b/src/rayon/set.rs index c92e2cd9..7b11befe 100644 --- a/src/rayon/set.rs +++ b/src/rayon/set.rs @@ -7,7 +7,7 @@ use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, Pa impl ParallelExtend for DashSet where K: Send + Sync + Eq + Hash, - S: Send + Sync + Clone + BuildHasher, + S: Send + Sync + BuildHasher, { fn par_extend(&mut self, par_iter: I) where @@ -22,7 +22,7 @@ where impl ParallelExtend for &'_ DashSet where K: Send + Sync + Eq + Hash, - S: Send + Sync + Clone + BuildHasher, + S: Send + Sync + BuildHasher, { fn par_extend(&mut self, par_iter: I) where @@ -38,7 +38,7 @@ where impl FromParallelIterator for DashSet where K: Send + Sync + Eq + Hash, - S: Send + Sync + Clone + Default + BuildHasher, + S: Send + Sync + BuildHasher + Default, { fn from_par_iter(par_iter: I) -> Self where @@ -52,8 +52,8 @@ where impl IntoParallelIterator for DashSet where - K: Send + Eq + Hash, - S: Send + Clone + BuildHasher, + K: Send, + S: Send, { type Iter = OwningIter; type Item = K; @@ -71,7 +71,7 @@ pub struct OwningIter { impl ParallelIterator for OwningIter where - K: Send + Eq + Hash, + K: Send, { type Item = K; @@ -86,8 +86,8 @@ where // This impl also enables `IntoParallelRefIterator::par_iter` impl<'a, K, S> IntoParallelIterator for &'a DashSet where - K: Send + Sync + Eq + Hash, - S: Send + Sync + Clone + BuildHasher, + K: Send + Sync, + S: Send + Sync, { type Iter = Iter<'a, K>; type Item = RefMulti<'a, K>; @@ -105,7 +105,7 @@ pub struct Iter<'a, K> { impl<'a, K> ParallelIterator for Iter<'a, K> where - K: Send + Sync + Eq + Hash, + K: Send + Sync, { type Item = RefMulti<'a, K>; diff --git a/src/read_only.rs b/src/read_only.rs index f31af489..81eb8783 100644 --- a/src/read_only.rs +++ b/src/read_only.rs @@ -1,7 +1,7 @@ use crate::lock::RwLock; use crate::{DashMap, HashMap}; use cfg_if::cfg_if; -use core::fmt; +use core::fmt::{self, Debug}; use core::hash::{BuildHasher, Hash}; use crossbeam_utils::CachePadded; use equivalent::Equivalent; @@ -12,7 +12,12 @@ pub struct ReadOnlyView { pub(crate) map: DashMap, } -impl Clone for ReadOnlyView { +impl Clone for ReadOnlyView +where + K: Clone, + V: Clone, + S: Clone, +{ fn clone(&self) -> Self { Self { map: self.map.clone(), @@ -20,8 +25,10 @@ impl Clone for ReadOnlyView { } } -impl fmt::Debug - for ReadOnlyView +impl Debug for ReadOnlyView +where + K: Debug, + V: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.map.fmt(f) @@ -37,9 +44,7 @@ impl ReadOnlyView { pub fn into_inner(self) -> DashMap { self.map } -} -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView { /// Returns the number of elements in the map. pub fn len(&self) -> usize { self.map.len() @@ -55,41 +60,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView self.map.capacity() } - /// Returns `true` if the map contains a value for the specified key. - pub fn contains_key(&'a self, key: &Q) -> bool - where - Q: Hash + Equivalent + ?Sized, - { - self.get(key).is_some() - } - - /// Returns a reference to the value corresponding to the key. - pub fn get(&'a self, key: &Q) -> Option<&'a V> - where - Q: Hash + Equivalent + ?Sized, - { - self.get_key_value(key).map(|(_k, v)| v) - } - - /// Returns the key-value pair corresponding to the supplied key. - pub fn get_key_value(&'a self, key: &Q) -> Option<(&'a K, &'a V)> - where - Q: Hash + Equivalent + ?Sized, - { - let hash = self.map.hash_u64(&key); - - let idx = self.map.determine_shard(hash as usize); - - let shard = &self.map.shards[idx]; - let shard = unsafe { &*shard.data_ptr() }; - - shard - .find(hash, |(k, _v)| key.equivalent(k)) - .map(|(k, v)| (k, v)) - } - - /// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(&'a K, &'a V)`. - pub fn iter(&'a self) -> impl Iterator + 'a { + /// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(&K, &V)`. + pub fn iter(&self) -> impl Iterator { self.map .shards .iter() @@ -99,12 +71,12 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView } /// An iterator visiting all keys in arbitrary order. The iterator element type is `&'a K`. - pub fn keys(&'a self) -> impl Iterator + 'a { + pub fn keys(&self) -> impl Iterator { self.iter().map(|(k, _v)| k) } /// An iterator visiting all values in arbitrary order. The iterator element type is `&'a V`. - pub fn values(&'a self) -> impl Iterator + 'a { + pub fn values(&self) -> impl Iterator { self.iter().map(|(_k, v)| v) } @@ -135,6 +107,45 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView } } +impl ReadOnlyView +where + K: Eq + Hash, + S: BuildHasher, +{ + /// Returns `true` if the map contains a value for the specified key. + pub fn contains_key(&self, key: &Q) -> bool + where + Q: Hash + Equivalent + ?Sized, + { + self.get(key).is_some() + } + + /// Returns a reference to the value corresponding to the key. + pub fn get(&self, key: &Q) -> Option<&V> + where + Q: Hash + Equivalent + ?Sized, + { + self.get_key_value(key).map(|(_k, v)| v) + } + + /// Returns the key-value pair corresponding to the supplied key. + pub fn get_key_value(&self, key: &Q) -> Option<(&K, &V)> + where + Q: Hash + Equivalent + ?Sized, + { + let hash = self.map.hash_u64(&key); + + let idx = self.map.determine_shard(hash as usize); + + let shard = &self.map.shards[idx]; + let shard = unsafe { &*shard.data_ptr() }; + + shard + .find(hash, |(k, _v)| key.equivalent(k)) + .map(|(k, v)| (k, v)) + } +} + #[cfg(test)] mod tests { diff --git a/src/serde.rs b/src/serde.rs index 9e7d41c1..3cf9002e 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -10,11 +10,7 @@ pub struct DashMapVisitor { marker: PhantomData DashMap>, } -impl DashMapVisitor -where - K: Eq + Hash, - S: BuildHasher + Clone, -{ +impl DashMapVisitor { fn new() -> Self { DashMapVisitor { marker: PhantomData, @@ -26,7 +22,7 @@ impl<'de, K, V, S> Visitor<'de> for DashMapVisitor where K: Deserialize<'de> + Eq + Hash, V: Deserialize<'de>, - S: BuildHasher + Clone + Default, + S: BuildHasher + Default, { type Value = DashMap; @@ -53,21 +49,20 @@ impl<'de, K, V, S> Deserialize<'de> for DashMap where K: Deserialize<'de> + Eq + Hash, V: Deserialize<'de>, - S: BuildHasher + Clone + Default, + S: BuildHasher + Default, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - deserializer.deserialize_map(DashMapVisitor::::new()) + deserializer.deserialize_map(DashMapVisitor::new()) } } impl Serialize for DashMap where - K: Serialize + Eq + Hash, + K: Serialize, V: Serialize, - H: BuildHasher + Clone, { fn serialize(&self, serializer: S) -> Result where @@ -87,11 +82,7 @@ pub struct DashSetVisitor { marker: PhantomData DashSet>, } -impl DashSetVisitor -where - K: Eq + Hash, - S: BuildHasher + Clone, -{ +impl DashSetVisitor { fn new() -> Self { DashSetVisitor { marker: PhantomData, @@ -102,7 +93,7 @@ where impl<'de, K, S> Visitor<'de> for DashSetVisitor where K: Deserialize<'de> + Eq + Hash, - S: BuildHasher + Clone + Default, + S: BuildHasher + Default, { type Value = DashSet; @@ -128,20 +119,19 @@ where impl<'de, K, S> Deserialize<'de> for DashSet where K: Deserialize<'de> + Eq + Hash, - S: BuildHasher + Clone + Default, + S: BuildHasher + Default, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - deserializer.deserialize_seq(DashSetVisitor::::new()) + deserializer.deserialize_seq(DashSetVisitor::new()) } } impl Serialize for DashSet where - K: Serialize + Eq + Hash, - H: BuildHasher + Clone, + K: Serialize, { fn serialize(&self, serializer: S) -> Result where @@ -169,35 +159,35 @@ macro_rules! serialize_impl { } // Map -impl<'a, K: Eq + Hash, V: Serialize> Serialize for mapref::multiple::RefMulti<'a, K, V> { +impl<'a, K, V: Serialize> Serialize for mapref::multiple::RefMulti<'a, K, V> { serialize_impl! {} } -impl<'a, K: Eq + Hash, V: Serialize> Serialize for mapref::multiple::RefMutMulti<'a, K, V> { +impl<'a, K, V: Serialize> Serialize for mapref::multiple::RefMutMulti<'a, K, V> { serialize_impl! {} } -impl<'a, K: Eq + Hash, V: Serialize> Serialize for mapref::one::Ref<'a, K, V> { +impl<'a, K, V: Serialize> Serialize for mapref::one::Ref<'a, K, V> { serialize_impl! {} } -impl<'a, K: Eq + Hash, V: Serialize> Serialize for mapref::one::RefMut<'a, K, V> { +impl<'a, K, V: Serialize> Serialize for mapref::one::RefMut<'a, K, V> { serialize_impl! {} } -impl<'a, K: Eq + Hash, T: Serialize> Serialize for mapref::one::MappedRef<'a, K, T> { +impl<'a, K, T: Serialize> Serialize for mapref::one::MappedRef<'a, K, T> { serialize_impl! {} } -impl<'a, K: Eq + Hash, T: Serialize> Serialize for mapref::one::MappedRefMut<'a, K, T> { +impl<'a, K, T: Serialize> Serialize for mapref::one::MappedRefMut<'a, K, T> { serialize_impl! {} } // Set -impl<'a, V: Hash + Eq + Serialize> Serialize for setref::multiple::RefMulti<'a, V> { +impl<'a, V: Serialize> Serialize for setref::multiple::RefMulti<'a, V> { serialize_impl! {} } -impl<'a, V: Hash + Eq + Serialize> Serialize for setref::one::Ref<'a, V> { +impl<'a, V: Serialize> Serialize for setref::one::Ref<'a, V> { serialize_impl! {} } diff --git a/src/set.rs b/src/set.rs index 6165ed84..61d623a9 100644 --- a/src/set.rs +++ b/src/set.rs @@ -6,7 +6,7 @@ use crate::DashMap; #[cfg(feature = "raw-api")] use crate::HashMap; use cfg_if::cfg_if; -use core::fmt; +use core::fmt::{self, Debug}; use core::hash::{BuildHasher, Hash}; use core::iter::FromIterator; #[cfg(feature = "raw-api")] @@ -22,13 +22,20 @@ pub struct DashSet { pub(crate) inner: DashMap, } -impl fmt::Debug for DashSet { +impl Debug for DashSet +where + K: Debug, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.inner, f) + Debug::fmt(&self.inner, f) } } -impl Clone for DashSet { +impl Clone for DashSet +where + K: Clone, + S: Clone, +{ fn clone(&self) -> Self { Self { inner: self.inner.clone(), @@ -40,17 +47,13 @@ impl Clone for DashSet { } } -impl Default for DashSet -where - K: Eq + Hash, - S: Default + BuildHasher + Clone, -{ +impl Default for DashSet { fn default() -> Self { Self::with_hasher(Default::default()) } } -impl<'a, K: 'a + Eq + Hash> DashSet { +impl DashSet { /// Creates a new DashSet with a capacity of 0. /// /// # Examples @@ -81,7 +84,7 @@ impl<'a, K: 'a + Eq + Hash> DashSet { } } -impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { +impl DashSet { /// Creates a new DashMap with a capacity of 0 and the provided hasher. /// /// # Examples @@ -117,10 +120,93 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { } } - /// Hash a given item to produce a usize. - /// Uses the provided or default HashBuilder. - pub fn hash_usize(&self, item: &T) -> usize { - self.inner.hash_usize(item) + /// Returns how many keys the set can store without reallocating. + pub fn capacity(&self) -> usize { + self.inner.capacity() + } + + /// Fetches the total number of keys stored in the set. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashSet; + /// + /// let people = DashSet::new(); + /// people.insert("Albin"); + /// people.insert("Jones"); + /// people.insert("Charlie"); + /// assert_eq!(people.len(), 3); + /// ``` + pub fn len(&self) -> usize { + self.inner.len() + } + + /// Checks if the set is empty or not. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashSet; + /// + /// let map = DashSet::<()>::new(); + /// assert!(map.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + /// Creates an iterator over a DashMap yielding immutable references. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashSet; + /// + /// let words = DashSet::new(); + /// words.insert("hello"); + /// assert_eq!(words.iter().count(), 1); + /// ``` + pub fn iter(&self) -> Iter<'_, K> { + let iter = self.inner.iter(); + + Iter::new(iter) + } + + /// Retain elements that whose predicates return true + /// and discard elements whose predicates return false. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashSet; + /// + /// let people = DashSet::new(); + /// people.insert("Albin"); + /// people.insert("Jones"); + /// people.insert("Charlie"); + /// people.retain(|name| name.contains('i')); + /// assert_eq!(people.len(), 2); + /// ``` + pub fn retain(&self, mut f: impl FnMut(&K) -> bool) { + self.inner.retain(|k, _| f(k)) + } + + /// Removes all keys in the set. + /// + /// # Examples + /// + /// ``` + /// use dashmap::DashSet; + /// + /// let people = DashSet::new(); + /// people.insert("Albin"); + /// assert!(!people.is_empty()); + /// people.clear(); + /// assert!(people.is_empty()); + /// ``` + pub fn clear(&self) { + self.inner.clear() } cfg_if! { @@ -143,6 +229,18 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { } } } +} + +impl DashSet +where + K: Eq + Hash, + S: BuildHasher, +{ + /// Hash a given item to produce a usize. + /// Uses the provided or default HashBuilder. + pub fn hash_usize(&self, item: &T) -> usize { + self.inner.hash_usize(item) + } cfg_if! { if #[cfg(feature = "raw-api")] { @@ -252,23 +350,6 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { self.inner.remove_if(key, |k, _| f(k)).map(|(k, _)| k) } - /// Creates an iterator over a DashMap yielding immutable references. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashSet; - /// - /// let words = DashSet::new(); - /// words.insert("hello"); - /// assert_eq!(words.iter().count(), 1); - /// ``` - pub fn iter(&'a self) -> Iter<'a, K> { - let iter = self.inner.iter(); - - Iter::new(iter) - } - /// Get a reference to an entry in the set /// /// # Examples @@ -280,7 +361,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// youtubers.insert("Bosnian Bill"); /// assert_eq!(*youtubers.get("Bosnian Bill").unwrap(), "Bosnian Bill"); /// ``` - pub fn get(&'a self, key: &Q) -> Option> + pub fn get(&self, key: &Q) -> Option> where Q: Hash + Equivalent + ?Sized, { @@ -292,78 +373,6 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { self.inner.shrink_to_fit() } - /// Retain elements that whose predicates return true - /// and discard elements whose predicates return false. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashSet; - /// - /// let people = DashSet::new(); - /// people.insert("Albin"); - /// people.insert("Jones"); - /// people.insert("Charlie"); - /// people.retain(|name| name.contains('i')); - /// assert_eq!(people.len(), 2); - /// ``` - pub fn retain(&self, mut f: impl FnMut(&K) -> bool) { - self.inner.retain(|k, _| f(k)) - } - - /// Fetches the total number of keys stored in the set. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashSet; - /// - /// let people = DashSet::new(); - /// people.insert("Albin"); - /// people.insert("Jones"); - /// people.insert("Charlie"); - /// assert_eq!(people.len(), 3); - /// ``` - pub fn len(&self) -> usize { - self.inner.len() - } - - /// Checks if the set is empty or not. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashSet; - /// - /// let map = DashSet::<()>::new(); - /// assert!(map.is_empty()); - /// ``` - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } - - /// Removes all keys in the set. - /// - /// # Examples - /// - /// ``` - /// use dashmap::DashSet; - /// - /// let people = DashSet::new(); - /// people.insert("Albin"); - /// assert!(!people.is_empty()); - /// people.clear(); - /// assert!(people.is_empty()); - /// ``` - pub fn clear(&self) { - self.inner.clear() - } - - /// Returns how many keys the set can store without reallocating. - pub fn capacity(&self) -> usize { - self.inner.capacity() - } - /// Checks if the set contains a specific key. /// /// # Examples @@ -383,15 +392,15 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { } } -impl PartialEq for DashSet { +impl PartialEq for DashSet { fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.iter().all(|r| other.contains(r.key())) } } -impl Eq for DashSet {} +impl Eq for DashSet {} -impl IntoIterator for DashSet { +impl IntoIterator for DashSet { type Item = K; type IntoIter = OwningIter; @@ -401,7 +410,7 @@ impl IntoIterator for DashSet { } } -impl Extend for DashSet { +impl Extend for DashSet { fn extend>(&mut self, iter: T) { let iter = iter.into_iter().map(|k| (k, ())); @@ -409,7 +418,11 @@ impl Extend for DashSet { } } -impl FromIterator for DashSet { +impl FromIterator for DashSet +where + K: Eq + Hash, + S: BuildHasher + Default, +{ fn from_iter>(iter: I) -> Self { let mut set = DashSet::default(); @@ -422,8 +435,8 @@ impl FromIterator for DashSet #[cfg(feature = "typesize")] impl typesize::TypeSize for DashSet where - K: typesize::TypeSize + Eq + Hash, - S: typesize::TypeSize + Clone + BuildHasher, + K: typesize::TypeSize, + S: typesize::TypeSize, { fn extra_size(&self) -> usize { self.inner.extra_size() diff --git a/src/setref/multiple.rs b/src/setref/multiple.rs index 4806c346..8196edb8 100644 --- a/src/setref/multiple.rs +++ b/src/setref/multiple.rs @@ -1,12 +1,11 @@ use crate::mapref; -use core::hash::Hash; use core::ops::Deref; pub struct RefMulti<'a, K> { inner: mapref::multiple::RefMulti<'a, K, ()>, } -impl<'a, K: Eq + Hash> RefMulti<'a, K> { +impl<'a, K> RefMulti<'a, K> { pub(crate) fn new(inner: mapref::multiple::RefMulti<'a, K, ()>) -> Self { Self { inner } } @@ -16,7 +15,7 @@ impl<'a, K: Eq + Hash> RefMulti<'a, K> { } } -impl<'a, K: Eq + Hash> Deref for RefMulti<'a, K> { +impl<'a, K> Deref for RefMulti<'a, K> { type Target = K; fn deref(&self) -> &K { diff --git a/src/setref/one.rs b/src/setref/one.rs index 5f6d71da..e0a5a77b 100644 --- a/src/setref/one.rs +++ b/src/setref/one.rs @@ -1,12 +1,11 @@ use crate::mapref; -use core::hash::Hash; use core::ops::Deref; pub struct Ref<'a, K> { inner: mapref::one::Ref<'a, K, ()>, } -impl<'a, K: Eq + Hash> Ref<'a, K> { +impl<'a, K> Ref<'a, K> { pub(crate) fn new(inner: mapref::one::Ref<'a, K, ()>) -> Self { Self { inner } } @@ -16,7 +15,7 @@ impl<'a, K: Eq + Hash> Ref<'a, K> { } } -impl<'a, K: Eq + Hash> Deref for Ref<'a, K> { +impl<'a, K> Deref for Ref<'a, K> { type Target = K; fn deref(&self) -> &K {