From a2c401fa2d9670aaa57d2d9bd2d92856cdf1d4fc Mon Sep 17 00:00:00 2001 From: Tomek Karwowski Date: Thu, 10 Aug 2023 21:28:47 +0200 Subject: [PATCH 1/2] refactor: Send and Sync are autoimplemented if all attributes in a struct are Send and Sync --- src/iter.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/iter.rs b/src/iter.rs index ce50e739..616edf1f 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -75,22 +75,6 @@ impl Iterator for OwningIter { } } -unsafe impl Send for OwningIter -where - K: Eq + Hash + Send, - V: Send, - S: BuildHasher + Clone + Send, -{ -} - -unsafe impl Sync for OwningIter -where - K: Eq + Hash + Sync, - V: Sync, - S: BuildHasher + Clone + Sync, -{ -} - type GuardIter<'a, K, V, S> = ( Arc>>, hash_map::Iter<'a, K, SharedValue>, From a975d4cebda24d7fa76d0cb9a44c01561e585279 Mon Sep 17 00:00:00 2001 From: Tomek Karwowski Date: Fri, 11 Aug 2023 17:41:27 +0200 Subject: [PATCH 2/2] refactor: relax trait bounds on generic parameters Currently most impl blocks over types in dashmap use similar trait bounds (e.g., K: Eq + Hash) even when those traits aren't actually "used" in the implementations. This forces users writing generic code over dashmap objects to include the same restrictions in their impl blocks. By contrast, most standard library crates use the least restrictive bounds possible for each method, even if it's not clear why anyone would want to use those methods without common-sense trait bounds. In the worst case, this prevents users from deriving traits like Debug on generic types containing DashMaps. The implementation of Debug on DashMap doesn't ultimately use the Eq or Hash implementations on K (although some of the intermediate types it uses also have the spurious bounds), so this issue could be avoided by removing the trait bounds. This commit removes all spurious bounds, leaving only the necessary constraints on per-method basis. --- src/arbitrary.rs | 4 +- src/iter.rs | 37 ++++---- src/iter_set.rs | 27 +++--- src/lib.rs | 192 ++++++++++++++++++++++++++++------------- src/mapref/entry.rs | 8 +- src/mapref/multiple.rs | 20 ++--- src/mapref/one.rs | 43 +++++---- src/read_only.rs | 17 ++-- src/serde.rs | 12 +-- src/set.rs | 53 ++++++++---- src/setref/multiple.rs | 5 +- src/setref/one.rs | 5 +- src/t.rs | 77 +++++++++++------ 13 files changed, 295 insertions(+), 205 deletions(-) diff --git a/src/arbitrary.rs b/src/arbitrary.rs index a760964b..5776932a 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -1,9 +1,9 @@ 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, { diff --git a/src/iter.rs b/src/iter.rs index 616edf1f..e0201c11 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -4,7 +4,6 @@ use crate::lock::{RwLockReadGuard, RwLockWriteGuard}; use crate::t::Map; use crate::util::SharedValue; use crate::{DashMap, HashMap}; -use core::hash::{BuildHasher, Hash}; use core::mem; use hashbrown::hash_map; use std::collections::hash_map::RandomState; @@ -29,7 +28,7 @@ pub struct OwningIter { current: Option>, } -impl OwningIter { +impl OwningIter { pub(crate) fn new(map: DashMap) -> Self { Self { map, @@ -41,7 +40,7 @@ impl OwningIter { type GuardOwningIter = hash_map::IntoIter>; -impl Iterator for OwningIter { +impl Iterator for OwningIter { type Item = (K, V); fn next(&mut self) -> Option { @@ -102,7 +101,7 @@ pub struct Iter<'a, K, V, S = RandomState, M = DashMap> { current: Option>, } -impl<'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter<'i, K, V, S> { +impl<'i, K: Clone, V: Clone, S: Clone> Clone for Iter<'i, K, V, S> { fn clone(&self) -> Self { Iter::new(self.map) } @@ -110,23 +109,23 @@ impl<'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter< unsafe impl<'a, 'i, K, V, S, M> Send for Iter<'i, K, V, S, M> where - K: 'a + Eq + Hash + Send, + K: 'a + Send, V: 'a + Send, - S: 'a + BuildHasher + Clone, + S: 'a + Clone, M: Map<'a, K, V, S>, { } unsafe impl<'a, 'i, K, V, S, M> Sync for Iter<'i, K, V, S, M> where - K: 'a + Eq + Hash + Sync, + K: 'a + Sync, V: 'a + Sync, - S: 'a + BuildHasher + Clone, + S: 'a + Clone, M: Map<'a, K, V, S>, { } -impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter<'a, K, V, S, M> { +impl<'a, K, V, S: 'a, M: Map<'a, K, V, S>> Iter<'a, K, V, S, M> { pub(crate) fn new(map: &'a M) -> Self { Self { map, @@ -136,9 +135,7 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter } } -impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator - for Iter<'a, K, V, S, M> -{ +impl<'a, K, V, S: 'a, M: Map<'a, K, V, S>> Iterator for Iter<'a, K, V, S, M> { type Item = RefMulti<'a, K, V, S>; fn next(&mut self) -> Option { @@ -188,25 +185,23 @@ pub struct IterMut<'a, K, V, S = RandomState, M = DashMap> { unsafe impl<'a, 'i, K, V, S, M> Send for IterMut<'i, K, V, S, M> where - K: 'a + Eq + Hash + Send, + K: 'a + Send, V: 'a + Send, - S: 'a + BuildHasher + Clone, + S: 'a + Clone, M: Map<'a, K, V, S>, { } unsafe impl<'a, 'i, K, V, S, M> Sync for IterMut<'i, K, V, S, M> where - K: 'a + Eq + Hash + Sync, + K: 'a + Sync, V: 'a + Sync, - S: 'a + BuildHasher + Clone, + S: 'a + Clone, M: Map<'a, K, V, S>, { } -impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> - IterMut<'a, K, V, S, M> -{ +impl<'a, K, V, S: 'a, M: Map<'a, K, V, S>> IterMut<'a, K, V, S, M> { pub(crate) fn new(map: &'a M) -> Self { Self { map, @@ -216,9 +211,7 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> } } -impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator - for IterMut<'a, K, V, S, M> -{ +impl<'a, K, V, S: 'a, M: Map<'a, K, V, S>> Iterator for IterMut<'a, K, V, S, M> { type Item = RefMutMulti<'a, K, V, S>; fn next(&mut self) -> Option { diff --git a/src/iter_set.rs b/src/iter_set.rs index 619a5b50..dc2a261d 100644 --- a/src/iter_set.rs +++ b/src/iter_set.rs @@ -1,18 +1,17 @@ use crate::setref::multiple::RefMulti; use crate::t::Map; -use core::hash::{BuildHasher, 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 { @@ -22,15 +21,15 @@ impl Iterator for OwningIter { unsafe impl Send for OwningIter where - K: Eq + Hash + Send, - S: BuildHasher + Clone + Send, + K: Send, + S: Send, { } unsafe impl Sync for OwningIter where - K: Eq + Hash + Sync, - S: BuildHasher + Clone + Sync, + K: Sync, + S: Sync, { } @@ -40,29 +39,27 @@ pub struct Iter<'a, K, S, M> { unsafe impl<'a, 'i, K, S, M> Send for Iter<'i, K, S, M> where - K: 'a + Eq + Hash + Send, - S: 'a + BuildHasher + Clone, + K: 'a + Send, + S: 'a, M: Map<'a, K, (), S>, { } unsafe impl<'a, 'i, K, S, M> Sync for Iter<'i, K, S, M> where - K: 'a + Eq + Hash + Sync, - S: 'a + BuildHasher + Clone, + K: 'a + Sync, + S: 'a, M: Map<'a, K, (), S>, { } -impl<'a, K: Eq + Hash, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iter<'a, K, S, M> { +impl<'a, K, S: 'a, M: Map<'a, K, (), S>> Iter<'a, K, S, M> { pub(crate) fn new(inner: crate::iter::Iter<'a, K, (), S, M>) -> Self { Self { inner } } } -impl<'a, K: Eq + Hash, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iterator - for Iter<'a, K, S, M> -{ +impl<'a, K, S: 'a, M: Map<'a, K, (), S>> Iterator for Iter<'a, K, S, M> { type Item = RefMulti<'a, K, S>; fn next(&mut self) -> Option { diff --git a/src/lib.rs b/src/lib.rs index 34e5d8ba..4d1634f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,7 +91,21 @@ pub struct DashMap { hasher: S, } -impl Clone for DashMap { +impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug, S: 'a> fmt::Debug for DashMap { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut pmap = f.debug_map(); + + for r in self { + let (k, v) = r.pair(); + + pmap.entry(k, v); + } + + pmap.finish() + } +} + +impl Clone for DashMap { fn clone(&self) -> Self { let mut inner_shards = Vec::new(); @@ -111,7 +125,6 @@ impl Clone for DashMap { impl Default for DashMap where - K: Eq + Hash, S: Default + BuildHasher + Clone, { fn default() -> Self { @@ -119,7 +132,7 @@ where } } -impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap { +impl<'a, K: 'a, V: 'a> DashMap { /// Creates a new DashMap with a capacity of 0. /// /// # Examples @@ -190,7 +203,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap { } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { +impl<'a, K: 'a, V: 'a, S> 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) @@ -208,7 +221,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// let reviews = DashMap::with_hasher(s); /// reviews.insert("Veloren", "What a fantastic game!"); /// ``` - pub fn with_hasher(hasher: S) -> Self { + pub fn with_hasher(hasher: S) -> Self + where + S: Clone, + { Self::with_capacity_and_hasher(0, hasher) } @@ -225,7 +241,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// mappings.insert(2, 4); /// mappings.insert(8, 16); /// ``` - pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self { + pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self + where + S: Clone, + { Self::with_capacity_and_hasher_and_shard_amount(capacity, hasher, default_shard_amount()) } @@ -245,7 +264,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// mappings.insert(2, 4); /// mappings.insert(8, 16); /// ``` - pub fn with_hasher_and_shard_amount(hasher: S, shard_amount: usize) -> Self { + pub fn with_hasher_and_shard_amount(hasher: S, shard_amount: usize) -> Self + where + S: Clone, + { Self::with_capacity_and_hasher_and_shard_amount(0, hasher, shard_amount) } @@ -269,7 +291,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { mut capacity: usize, hasher: S, shard_amount: usize, - ) -> Self { + ) -> Self + where + S: Clone, + { assert!(shard_amount > 1); assert!(shard_amount.is_power_of_two()); @@ -294,7 +319,10 @@ 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 { + pub fn hash_usize(&self, item: &T) -> usize + where + S: BuildHasher, + { let mut hasher = self.hasher.build_hasher(); item.hash(&mut hasher); @@ -389,6 +417,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { where K: Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); self.determine_shard(hash) @@ -455,7 +484,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// let map = DashMap::new(); /// map.insert("I am the key!", "And I am the value!"); /// ``` - pub fn insert(&self, key: K, value: V) -> Option { + pub fn insert(&self, key: K, value: V) -> Option + where + K: Hash + Eq, + S: BuildHasher, + { self._insert(key, value) } @@ -474,8 +507,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn remove(&self, key: &Q) -> Option<(K, V)> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._remove(key) } @@ -503,16 +537,18 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn remove_if(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._remove_if(key, f) } pub fn remove_if_mut(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._remove_if_mut(key, f) } @@ -567,8 +603,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn get(&'a self, key: &Q) -> Option> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._get(key) } @@ -589,8 +626,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn get_mut(&'a self, key: &Q) -> Option> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._get_mut(key) } @@ -616,8 +654,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn try_get(&'a self, key: &Q) -> TryResult> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._try_get(key) } @@ -644,8 +683,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn try_get_mut(&'a self, key: &Q) -> TryResult> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._try_get_mut(key) } @@ -653,7 +693,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// Remove excess capacity to reduce memory usage. /// /// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map. - pub fn shrink_to_fit(&self) { + pub fn shrink_to_fit(&self) + where + K: Hash + Eq, + S: BuildHasher, + { self._shrink_to_fit(); } @@ -759,8 +803,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// If the given closure panics, then `alter` will abort the process pub fn alter(&self, key: &Q, f: impl FnOnce(&K, V) -> V) where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._alter(key, f); } @@ -810,8 +855,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// If the given closure panics, then `view` will abort the process pub fn view(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._view(key, f) } @@ -831,8 +877,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// ``` pub fn contains_key(&self, key: &Q) -> bool where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._contains_key(key) } @@ -841,7 +888,11 @@ 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, S> { + pub fn entry(&'a self, key: K) -> Entry<'a, K, V, S> + where + K: Hash + Eq, + S: BuildHasher, + { self._entry(key) } @@ -849,7 +900,11 @@ 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(&'a self, key: K) -> Option> + where + K: Hash + Eq, + S: BuildHasher, + { self._try_entry(key) } @@ -861,7 +916,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { /// /// 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> { + pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> + where + K: Hash + Eq, + S: BuildHasher, + { for shard in self.shards.iter() { shard .write() @@ -872,9 +931,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> - for DashMap -{ +impl<'a, K: 'a, V: 'a, S: 'a> Map<'a, K, V, S> for DashMap { fn _shard_count(&self) -> usize { self.shards.len() } @@ -915,7 +972,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> self.shards.get_unchecked(i).try_write() } - fn _insert(&self, key: K, value: V) -> Option { + fn _insert(&self, key: K, value: V) -> Option + where + K: Hash + Eq, + S: BuildHasher, + { let hash = self.hash_usize(&key); let idx = self.determine_shard(hash); @@ -929,8 +990,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _remove(&self, key: &Q) -> Option<(K, V)> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -943,8 +1005,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _remove_if(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -970,8 +1033,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _remove_if_mut(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -1005,8 +1069,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _get(&'a self, key: &Q) -> Option> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -1027,8 +1092,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _get_mut(&'a self, key: &Q) -> Option> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -1049,8 +1115,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _try_get(&'a self, key: &Q) -> TryResult> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -1074,8 +1141,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _try_get_mut(&'a self, key: &Q) -> TryResult> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.hash_usize(&key); @@ -1097,7 +1165,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } } - fn _shrink_to_fit(&self) { + fn _shrink_to_fit(&self) + where + K: Hash + Eq, + S: BuildHasher, + { self.shards.iter().for_each(|s| s.write().shrink_to_fit()); } @@ -1117,8 +1189,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _alter(&self, key: &Q, f: impl FnOnce(&K, V) -> V) where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { if let Some(mut r) = self.get_mut(key) { util::map_in_place_2(r.pair_mut(), f); @@ -1135,8 +1208,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> fn _view(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self.get(key).map(|r| { let (k, v) = r.pair(); @@ -1144,7 +1218,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> }) } - fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> { + fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> + where + K: Hash + Eq, + S: BuildHasher, + { let hash = self.hash_usize(&key); let idx = self.determine_shard(hash); @@ -1162,7 +1240,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } } - fn _try_entry(&'a self, key: K) -> Option> { + fn _try_entry(&'a self, key: K) -> Option> + where + K: Hash + Eq, + S: BuildHasher, + { let hash = self.hash_usize(&key); let idx = self.determine_shard(hash); @@ -1188,28 +1270,15 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } } - fn _hasher(&self) -> S { + fn _hasher(&self) -> S + where + S: Clone, + { self.hasher.clone() } } -impl fmt::Debug - for DashMap -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut pmap = f.debug_map(); - - for r in self { - let (k, v) = r.pair(); - - pmap.entry(k, v); - } - - pmap.finish() - } -} - -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> Shl<(K, V)> for &'a DashMap { +impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher> Shl<(K, V)> for &'a DashMap { type Output = Option; fn shl(self, pair: (K, V)) -> Self::Output { @@ -1265,7 +1334,7 @@ where } } -impl IntoIterator for DashMap { +impl IntoIterator for DashMap { type Item = (K, V); type IntoIter = OwningIter; @@ -1275,7 +1344,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, S>; type IntoIter = Iter<'a, K, V, S, DashMap>; @@ -1285,7 +1354,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap Extend<(K, V)> for DashMap { +impl Extend<(K, V)> for DashMap { fn extend>(&mut self, intoiter: I) { for pair in intoiter.into_iter() { self.insert(pair.0, pair.1); @@ -1352,7 +1421,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 e9e6b913..afeb2958 100644 --- a/src/mapref/entry.rs +++ b/src/mapref/entry.rs @@ -119,8 +119,8 @@ pub struct VacantEntry<'a, K, V, S = RandomState> { 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> {} +unsafe impl<'a, K: Sync, V: Sync, S> Send for VacantEntry<'a, K, V, S> {} +unsafe impl<'a, K: Sync, V: Sync, S> 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>, key: K) -> Self { @@ -178,8 +178,8 @@ pub struct OccupiedEntry<'a, K, V, S = RandomState> { 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> {} +unsafe impl<'a, K: Sync, V: Sync, S> Send for OccupiedEntry<'a, K, V, S> {} +unsafe impl<'a, K: Sync, V: Sync, S> 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( diff --git a/src/mapref/multiple.rs b/src/mapref/multiple.rs index 53a8a7e5..6ac491dc 100644 --- a/src/mapref/multiple.rs +++ b/src/mapref/multiple.rs @@ -1,7 +1,5 @@ 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; @@ -12,10 +10,10 @@ pub struct RefMulti<'a, K, V, S = RandomState> { 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> {} +unsafe impl<'a, K: Sync, V: Sync, S> Send for RefMulti<'a, K, V, S> {} +unsafe impl<'a, K: Sync, V: Sync, S> Sync for RefMulti<'a, K, V, S> {} -impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> { +impl<'a, K, V, S> RefMulti<'a, K, V, S> { pub(crate) unsafe fn new( guard: Arc>>, k: *const K, @@ -41,7 +39,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMulti<'a, K, V, S> { +impl<'a, K, V, S> Deref for RefMulti<'a, K, V, S> { type Target = V; fn deref(&self) -> &V { @@ -55,10 +53,10 @@ pub struct RefMutMulti<'a, K, V, S = RandomState> { 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> {} +unsafe impl<'a, K: Sync, V: Sync, S> Send for RefMutMulti<'a, K, V, S> {} +unsafe impl<'a, K: Sync, V: Sync, S> Sync for RefMutMulti<'a, K, V, S> {} -impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> { +impl<'a, K, V, S> RefMutMulti<'a, K, V, S> { pub(crate) unsafe fn new( guard: Arc>>, k: *const K, @@ -92,7 +90,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMutMulti<'a, K, V, S> { +impl<'a, K, V, S> Deref for RefMutMulti<'a, K, V, S> { type Target = V; fn deref(&self) -> &V { @@ -100,7 +98,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMutMulti<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMutMulti<'a, K, V, S> { +impl<'a, K, V, S> DerefMut for RefMutMulti<'a, K, V, S> { fn deref_mut(&mut self) -> &mut V { self.value_mut() } diff --git a/src/mapref/one.rs b/src/mapref/one.rs index fd385309..6abfd16f 100644 --- a/src/mapref/one.rs +++ b/src/mapref/one.rs @@ -1,6 +1,5 @@ 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}; @@ -11,10 +10,10 @@ pub struct Ref<'a, K, V, S = RandomState> { 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> {} +unsafe impl<'a, K: Sync, V: Sync, S> Send for Ref<'a, K, V, S> {} // TODO: typo? Shouldn't the impl contraits be Send not Sync? +unsafe impl<'a, K: Sync, V: Sync, S> Sync for Ref<'a, K, V, S> {} -impl<'a, K: Eq + Hash, V, S: BuildHasher> Ref<'a, K, V, S> { +impl<'a, K, V, S> Ref<'a, K, V, S> { pub(crate) unsafe fn new( guard: RwLockReadGuard<'a, HashMap>, k: *const K, @@ -66,7 +65,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Ref<'a, K, V, S> { } } -impl<'a, K: Eq + Hash + Debug, V: Debug, S: BuildHasher> Debug for Ref<'a, K, V, S> { +impl<'a, K: Debug, V: Debug, S> Debug for Ref<'a, K, V, S> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("Ref") .field("k", &self.k) @@ -75,7 +74,7 @@ impl<'a, K: Eq + Hash + Debug, V: Debug, S: BuildHasher> Debug for Ref<'a, K, V, } } -impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for Ref<'a, K, V, S> { +impl<'a, K, V, S> Deref for Ref<'a, K, V, S> { type Target = V; fn deref(&self) -> &V { @@ -89,10 +88,10 @@ pub struct RefMut<'a, K, V, S = RandomState> { 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> {} +unsafe impl<'a, K: Sync, V: Sync, S> Send for RefMut<'a, K, V, S> {} +unsafe impl<'a, K: Sync, V: Sync, S> Sync for RefMut<'a, K, V, S> {} -impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMut<'a, K, V, S> { +impl<'a, K, V, S> RefMut<'a, K, V, S> { pub(crate) unsafe fn new( guard: RwLockWriteGuard<'a, HashMap>, k: *const K, @@ -154,7 +153,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMut<'a, K, V, S> { } } -impl<'a, K: Eq + Hash + Debug, V: Debug, S: BuildHasher> Debug for RefMut<'a, K, V, S> { +impl<'a, K: Debug, V: Debug, S> Debug for RefMut<'a, K, V, S> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("RefMut") .field("k", &self.k) @@ -163,7 +162,7 @@ impl<'a, K: Eq + Hash + Debug, V: Debug, S: BuildHasher> Debug for RefMut<'a, K, } } -impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMut<'a, K, V, S> { +impl<'a, K, V, S> Deref for RefMut<'a, K, V, S> { type Target = V; fn deref(&self) -> &V { @@ -171,7 +170,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMut<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMut<'a, K, V, S> { +impl<'a, K, V, S> DerefMut for RefMut<'a, K, V, S> { fn deref_mut(&mut self) -> &mut V { self.value_mut() } @@ -183,7 +182,7 @@ pub struct MappedRef<'a, K, V, T, S = RandomState> { v: *const T, } -impl<'a, K: Eq + Hash, V, T, S: BuildHasher> MappedRef<'a, K, V, T, S> { +impl<'a, K, V, T, S> MappedRef<'a, K, V, T, S> { pub fn key(&self) -> &K { self.pair().0 } @@ -224,7 +223,7 @@ impl<'a, K: Eq + Hash, V, T, S: BuildHasher> MappedRef<'a, K, V, T, S> { } } -impl<'a, K: Eq + Hash + Debug, V, T: Debug, S: BuildHasher> Debug for MappedRef<'a, K, V, T, S> { +impl<'a, K: Debug, V, T: Debug, S> 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) @@ -233,7 +232,7 @@ impl<'a, K: Eq + Hash + Debug, V, T: Debug, S: BuildHasher> Debug for MappedRef< } } -impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRef<'a, K, V, T, S> { +impl<'a, K, V, T, S> Deref for MappedRef<'a, K, V, T, S> { type Target = T; fn deref(&self) -> &T { @@ -241,15 +240,13 @@ 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> { +impl<'a, K, 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> -{ +impl<'a, K, V, T: AsRef, TDeref: ?Sized> AsRef for MappedRef<'a, K, V, T> { fn as_ref(&self) -> &TDeref { self.value().as_ref() } @@ -261,7 +258,7 @@ pub struct MappedRefMut<'a, K, V, T, S = RandomState> { v: *mut T, } -impl<'a, K: Eq + Hash, V, T, S: BuildHasher> MappedRefMut<'a, K, V, T, S> { +impl<'a, K, V, T, S> MappedRefMut<'a, K, V, T, S> { pub fn key(&self) -> &K { self.pair().0 } @@ -311,7 +308,7 @@ impl<'a, K: Eq + Hash, V, T, S: BuildHasher> MappedRefMut<'a, K, V, T, S> { } } -impl<'a, K: Eq + Hash + Debug, V, T: Debug, S: BuildHasher> Debug for MappedRefMut<'a, K, V, T, S> { +impl<'a, K: Debug, V, T: Debug, S> 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) @@ -320,7 +317,7 @@ impl<'a, K: Eq + Hash + Debug, V, T: Debug, S: BuildHasher> Debug for MappedRefM } } -impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRefMut<'a, K, V, T, S> { +impl<'a, K, V, T, S> Deref for MappedRefMut<'a, K, V, T, S> { type Target = T; fn deref(&self) -> &T { @@ -328,7 +325,7 @@ impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRefMut<'a, K, V, T, } } -impl<'a, K: Eq + Hash, V, T, S: BuildHasher> DerefMut for MappedRefMut<'a, K, V, T, S> { +impl<'a, K, V, T, S> DerefMut for MappedRefMut<'a, K, V, T, S> { fn deref_mut(&mut self) -> &mut T { self.value_mut() } diff --git a/src/read_only.rs b/src/read_only.rs index 42ee4433..897f1b2c 100644 --- a/src/read_only.rs +++ b/src/read_only.rs @@ -12,7 +12,7 @@ pub struct ReadOnlyView { pub(crate) map: DashMap, } -impl Clone for ReadOnlyView { +impl Clone for ReadOnlyView { fn clone(&self) -> Self { Self { map: self.map.clone(), @@ -20,9 +20,7 @@ impl Clone for ReadOnlyView { } } -impl fmt::Debug - for ReadOnlyView -{ +impl fmt::Debug for ReadOnlyView { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.map.fmt(f) } @@ -39,7 +37,7 @@ impl ReadOnlyView { } } -impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView { +impl<'a, K: 'a, V: 'a, S> ReadOnlyView { /// Returns the number of elements in the map. pub fn len(&self) -> usize { self.map.len() @@ -58,8 +56,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView /// Returns `true` if the map contains a value for the specified key. pub fn contains_key(&'a self, key: &Q) -> bool where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.map.hash_usize(&key); @@ -73,8 +72,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView /// Returns a reference to the value corresponding to the key. pub fn get(&'a self, key: &Q) -> Option<&'a V> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.map.hash_usize(&key); @@ -88,8 +88,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView /// 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 - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { let hash = self.map.hash_usize(&key); diff --git a/src/serde.rs b/src/serde.rs index 6abeb069..e568a91c 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, @@ -87,11 +83,7 @@ pub struct DashSetVisitor { marker: PhantomData DashSet>, } -impl DashSetVisitor -where - K: Eq + Hash, - S: BuildHasher + Clone, -{ +impl DashSetVisitor { fn new() -> Self { DashSetVisitor { marker: PhantomData, diff --git a/src/set.rs b/src/set.rs index 1a561770..207a1a62 100644 --- a/src/set.rs +++ b/src/set.rs @@ -20,13 +20,13 @@ pub struct DashSet { pub(crate) inner: DashMap, } -impl fmt::Debug for DashSet { +impl fmt::Debug for DashSet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.inner, f) } } -impl Clone for DashSet { +impl Clone for DashSet { fn clone(&self) -> Self { Self { inner: self.inner.clone(), @@ -40,7 +40,6 @@ impl Clone for DashSet { impl Default for DashSet where - K: Eq + Hash, S: Default + BuildHasher + Clone, { fn default() -> Self { @@ -48,7 +47,7 @@ where } } -impl<'a, K: 'a + Eq + Hash> DashSet { +impl<'a, K: 'a> DashSet { /// Creates a new DashSet with a capacity of 0. /// /// # Examples @@ -79,7 +78,7 @@ impl<'a, K: 'a + Eq + Hash> DashSet { } } -impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { +impl<'a, K: 'a, S> DashSet { /// Creates a new DashMap with a capacity of 0 and the provided hasher. /// /// # Examples @@ -92,7 +91,10 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// let games = DashSet::with_hasher(s); /// games.insert("Veloren"); /// ``` - pub fn with_hasher(hasher: S) -> Self { + pub fn with_hasher(hasher: S) -> Self + where + S: Clone, + { Self::with_capacity_and_hasher(0, hasher) } @@ -109,7 +111,10 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// numbers.insert(2); /// numbers.insert(8); /// ``` - pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self { + pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self + where + S: Clone, + { Self { inner: DashMap::with_capacity_and_hasher(capacity, hasher), } @@ -117,7 +122,10 @@ 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 { + pub fn hash_usize(&self, item: &T) -> usize + where + S: BuildHasher, + { self.inner.hash_usize(item) } @@ -163,6 +171,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { where K: Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher { self.inner.determine_map(key) } @@ -201,7 +210,11 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// let set = DashSet::new(); /// set.insert("I am the key!"); /// ``` - pub fn insert(&self, key: K) -> bool { + pub fn insert(&self, key: K) -> bool + where + K: Hash + Eq, + S: BuildHasher, + { self.inner.insert(key, ()).is_none() } @@ -218,8 +231,9 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// ``` pub fn remove(&self, key: &Q) -> Option where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self.inner.remove(key).map(|(k, _)| k) } @@ -245,8 +259,9 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// ``` pub fn remove_if(&self, key: &Q, f: impl FnOnce(&K) -> bool) -> Option where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { // TODO: Don't create another closure around f self.inner.remove_if(key, |k, _| f(k)).map(|(k, _)| k) @@ -282,14 +297,19 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// ``` pub fn get(&'a self, key: &Q) -> Option> where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self.inner.get(key).map(Ref::new) } /// Remove excess capacity to reduce memory usage. - pub fn shrink_to_fit(&self) { + pub fn shrink_to_fit(&self) + where + K: Hash + Eq, + S: BuildHasher, + { self.inner.shrink_to_fit() } @@ -378,14 +398,15 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet { /// ``` pub fn contains(&self, key: &Q) -> bool where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self.inner.contains_key(key) } } -impl IntoIterator for DashSet { +impl IntoIterator for DashSet { type Item = K; type IntoIter = OwningIter; @@ -395,7 +416,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, ())); diff --git a/src/setref/multiple.rs b/src/setref/multiple.rs index 21e7ed4a..0a8b413f 100644 --- a/src/setref/multiple.rs +++ b/src/setref/multiple.rs @@ -1,12 +1,11 @@ use crate::mapref; -use core::hash::{BuildHasher, Hash}; use core::ops::Deref; use std::collections::hash_map::RandomState; pub struct RefMulti<'a, K, S = RandomState> { inner: mapref::multiple::RefMulti<'a, K, (), S>, } -impl<'a, K: Eq + Hash, S: BuildHasher> RefMulti<'a, K, S> { +impl<'a, K, S> RefMulti<'a, K, S> { pub(crate) fn new(inner: mapref::multiple::RefMulti<'a, K, (), S>) -> Self { Self { inner } } @@ -16,7 +15,7 @@ impl<'a, K: Eq + Hash, S: BuildHasher> RefMulti<'a, K, S> { } } -impl<'a, K: Eq + Hash, S: BuildHasher> Deref for RefMulti<'a, K, S> { +impl<'a, K, S> Deref for RefMulti<'a, K, S> { type Target = K; fn deref(&self) -> &K { diff --git a/src/setref/one.rs b/src/setref/one.rs index 0787187d..cfeeb7af 100644 --- a/src/setref/one.rs +++ b/src/setref/one.rs @@ -1,12 +1,11 @@ use crate::mapref; -use core::hash::{BuildHasher, Hash}; use core::ops::Deref; use std::collections::hash_map::RandomState; pub struct Ref<'a, K, S = RandomState> { inner: mapref::one::Ref<'a, K, (), S>, } -impl<'a, K: Eq + Hash, S: BuildHasher> Ref<'a, K, S> { +impl<'a, K, S> Ref<'a, K, S> { pub(crate) fn new(inner: mapref::one::Ref<'a, K, (), S>) -> Self { Self { inner } } @@ -16,7 +15,7 @@ impl<'a, K: Eq + Hash, S: BuildHasher> Ref<'a, K, S> { } } -impl<'a, K: Eq + Hash, S: BuildHasher> Deref for Ref<'a, K, S> { +impl<'a, K, S> Deref for Ref<'a, K, S> { type Target = K; fn deref(&self) -> &K { diff --git a/src/t.rs b/src/t.rs index 5e1fedcc..c64e5bef 100644 --- a/src/t.rs +++ b/src/t.rs @@ -7,10 +7,11 @@ use crate::mapref::one::{Ref, RefMut}; use crate::try_result::TryResult; use crate::HashMap; use core::borrow::Borrow; -use core::hash::{BuildHasher, Hash}; +use core::hash::Hash; +use std::hash::BuildHasher; /// Implementation detail that is exposed due to generic constraints in public types. -pub trait Map<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + Clone + BuildHasher> { +pub trait Map<'a, K: 'a, V: 'a, S: 'a> { fn _shard_count(&self) -> usize; /// # Safety @@ -44,22 +45,28 @@ pub trait Map<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + Clone + BuildHasher> { i: usize, ) -> Option>>; - fn _insert(&self, key: K, value: V) -> Option; + fn _insert(&self, key: K, value: V) -> Option + where + K: Hash + Eq, + S: BuildHasher; fn _remove(&self, key: &Q) -> Option<(K, V)> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _remove_if(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _remove_if_mut(&self, key: &Q, f: impl FnOnce(&K, &mut V) -> bool) -> Option<(K, V)> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _iter(&'a self) -> Iter<'a, K, V, S, Self> where @@ -71,25 +78,32 @@ pub trait Map<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + Clone + BuildHasher> { fn _get(&'a self, key: &Q) -> Option> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _get_mut(&'a self, key: &Q) -> Option> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _try_get(&'a self, key: &Q) -> TryResult> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _try_get_mut(&'a self, key: &Q) -> TryResult> where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; - fn _shrink_to_fit(&self); + fn _shrink_to_fit(&self) + where + K: Hash + Eq, + S: BuildHasher; fn _retain(&self, f: impl FnMut(&K, &mut V) -> bool); @@ -99,21 +113,31 @@ pub trait Map<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + Clone + BuildHasher> { fn _alter(&self, key: &Q, f: impl FnOnce(&K, V) -> V) where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; fn _alter_all(&self, f: impl FnMut(&K, V) -> V); fn _view(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option where - K: Borrow, - Q: Hash + Eq + ?Sized; + K: Hash + Eq + Borrow, + Q: Hash + Eq + ?Sized, + S: BuildHasher; - fn _entry(&'a self, key: K) -> Entry<'a, K, V, S>; + fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> + where + K: Hash + Eq, + S: BuildHasher; - fn _try_entry(&'a self, key: K) -> Option>; + fn _try_entry(&'a self, key: K) -> Option> + where + K: Hash + Eq, + S: BuildHasher; - fn _hasher(&self) -> S; + fn _hasher(&self) -> S + where + S: Clone; // provided fn _clear(&self) { @@ -122,8 +146,9 @@ pub trait Map<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + Clone + BuildHasher> { fn _contains_key(&'a self, key: &Q) -> bool where - K: Borrow, + K: Hash + Eq + Borrow, Q: Hash + Eq + ?Sized, + S: BuildHasher, { self._get(key).is_some() }