From 21e21840ea96266674f2afb48334b50f3dcf0b06 Mon Sep 17 00:00:00 2001 From: Acrimon Date: Wed, 15 Jan 2020 16:13:23 +0100 Subject: [PATCH] Fixed a multitide of issues and added some trait impls. --- src/lib.rs | 34 ++++++++++++++++++++++++++++++---- src/mapref/entry.rs | 3 ++- src/mapref/multiple.rs | 30 +++++++++++++++++++----------- src/mapref/one.rs | 5 +++-- 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a3c9b4bd..653736a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,9 +12,11 @@ use cfg_if::cfg_if; use fxhash::FxBuildHasher; use iter::{Iter, IterMut}; use mapref::entry::{Entry, OccupiedEntry, VacantEntry}; +use mapref::multiple::RefMulti; use mapref::one::{Ref, RefMut}; use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::borrow::Borrow; +use std::fmt; use std::hash::{BuildHasher, Hash}; use std::iter::FromIterator; use std::ops::{BitAnd, BitOr, Shl, Shr, Sub}; @@ -30,10 +32,12 @@ cfg_if! { type HashMap = std::collections::HashMap, S>; +#[inline] fn shard_amount() -> usize { (num_cpus::get() * 4).next_power_of_two() } +#[inline] fn ncb(shard_amount: usize) -> usize { (shard_amount as f32).log2() as usize } @@ -202,10 +206,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = fxhash::hash64(&key); + let hash = fxhash::hash(&key); let shift = util::ptr_size_bits() - self.ncb; - (hash >> shift) as usize + (hash >> shift) } } else { #[inline] @@ -214,10 +218,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap { K: Borrow, Q: Hash + Eq + ?Sized, { - let hash = fxhash::hash64(&key); + let hash = fxhash::hash(&key); let shift = util::ptr_size_bits() - self.ncb; - (hash >> shift) as usize + (hash >> shift) } } } @@ -636,6 +640,19 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S> } } +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 { type Output = Option; @@ -697,6 +714,15 @@ where } } +impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap { + type Item = RefMulti<'a, K, V, S>; + type IntoIter = Iter<'a, K, V, S, DashMap>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + impl Extend<(K, V)> for DashMap { fn extend>(&mut self, intoiter: I) { for pair in intoiter.into_iter() { diff --git a/src/mapref/entry.rs b/src/mapref/entry.rs index 3fc5d421..b8eda889 100644 --- a/src/mapref/entry.rs +++ b/src/mapref/entry.rs @@ -2,12 +2,13 @@ use super::one::RefMut; use crate::util; use crate::util::SharedValue; use crate::HashMap; +use fxhash::FxBuildHasher; use parking_lot::RwLockWriteGuard; use std::hash::{BuildHasher, Hash}; use std::mem; use std::ptr; -pub enum Entry<'a, K: Eq + Hash, V, S: BuildHasher> { +pub enum Entry<'a, K: Eq + Hash, V, S: BuildHasher = FxBuildHasher> { Occupied(OccupiedEntry<'a, K, V, S>), Vacant(VacantEntry<'a, K, V, S>), } diff --git a/src/mapref/multiple.rs b/src/mapref/multiple.rs index 10be02bc..b6b1175b 100644 --- a/src/mapref/multiple.rs +++ b/src/mapref/multiple.rs @@ -1,21 +1,26 @@ use crate::HashMap; +use fxhash::FxBuildHasher; use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; +use std::hash::BuildHasher; use std::hash::Hash; use std::ops::{Deref, DerefMut}; use std::sync::Arc; // -- Shared -pub struct RefMulti<'a, K: Eq + Hash, V, S> { +pub struct RefMulti<'a, K: Eq + Hash, V, S: BuildHasher = FxBuildHasher> { _guard: Arc>>, k: &'a K, v: &'a V, } -unsafe impl<'a, K: Eq + Hash + Send, V: Send, S> Send for RefMulti<'a, K, V, S> {} -unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S> Sync for RefMulti<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for RefMulti<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync + for RefMulti<'a, K, V, S> +{ +} -impl<'a, K: Eq + Hash, V, S> RefMulti<'a, K, V, S> { +impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> { #[inline(always)] pub(crate) fn new( guard: Arc>>, @@ -45,7 +50,7 @@ impl<'a, K: Eq + Hash, V, S> RefMulti<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S> Deref for RefMulti<'a, K, V, S> { +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMulti<'a, K, V, S> { type Target = V; #[inline(always)] @@ -58,16 +63,19 @@ impl<'a, K: Eq + Hash, V, S> Deref for RefMulti<'a, K, V, S> { // -- Unique -pub struct RefMutMulti<'a, K: Eq + Hash, V, S> { +pub struct RefMutMulti<'a, K: Eq + Hash, V, S: BuildHasher = FxBuildHasher> { _guard: Arc>>, k: &'a K, v: &'a mut V, } -unsafe impl<'a, K: Eq + Hash + Send, V: Send, S> Send for RefMutMulti<'a, K, V, S> {} -unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S> Sync for RefMutMulti<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Send, V: Send, S: BuildHasher> Send for RefMutMulti<'a, K, V, S> {} +unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync + for RefMutMulti<'a, K, V, S> +{ +} -impl<'a, K: Eq + Hash, V, S> RefMutMulti<'a, K, V, S> { +impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> { #[inline(always)] pub(crate) fn new( guard: Arc>>, @@ -107,7 +115,7 @@ impl<'a, K: Eq + Hash, V, S> RefMutMulti<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S> Deref for RefMutMulti<'a, K, V, S> { +impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMutMulti<'a, K, V, S> { type Target = V; #[inline(always)] @@ -116,7 +124,7 @@ impl<'a, K: Eq + Hash, V, S> Deref for RefMutMulti<'a, K, V, S> { } } -impl<'a, K: Eq + Hash, V, S> DerefMut for RefMutMulti<'a, K, V, S> { +impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMutMulti<'a, K, V, S> { #[inline(always)] fn deref_mut(&mut self) -> &mut V { self.value_mut() diff --git a/src/mapref/one.rs b/src/mapref/one.rs index dead442d..2a8fa515 100644 --- a/src/mapref/one.rs +++ b/src/mapref/one.rs @@ -1,4 +1,5 @@ use crate::HashMap; +use fxhash::FxBuildHasher; use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; use std::hash::{BuildHasher, Hash}; use std::marker::PhantomData; @@ -6,7 +7,7 @@ use std::ops::{Deref, DerefMut}; // -- Shared -pub struct Ref<'a, K: Eq + Hash, V, S: BuildHasher> { +pub struct Ref<'a, K: Eq + Hash, V, S: BuildHasher = FxBuildHasher> { _guard: RwLockReadGuard<'a, HashMap>, k: &'a K, v: &'a V, @@ -59,7 +60,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for Ref<'a, K, V, S> { // -- Unique -pub struct RefMut<'a, K: Eq + Hash, V, S: BuildHasher> { +pub struct RefMut<'a, K: Eq + Hash, V, S: BuildHasher = FxBuildHasher> { _guard: RwLockWriteGuard<'a, HashMap>, k: &'a K, v: &'a mut V,