Skip to content

Commit

Permalink
Fixed a multitide of issues and added some trait impls.
Browse files Browse the repository at this point in the history
  • Loading branch information
xacrimon committed Jan 15, 2020
1 parent 9d597a3 commit 21e2184
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 18 deletions.
34 changes: 30 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -30,10 +32,12 @@ cfg_if! {

type HashMap<K, V, S> = std::collections::HashMap<K, SharedValue<V>, 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
}
Expand Down Expand Up @@ -202,10 +206,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
K: Borrow<Q>,
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]
Expand All @@ -214,10 +218,10 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
K: Borrow<Q>,
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)
}
}
}
Expand Down Expand Up @@ -636,6 +640,19 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
}
}

impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug
for DashMap<K, V, S>
{
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<K, V, S> {
type Output = Option<V>;

Expand Down Expand Up @@ -697,6 +714,15 @@ where
}
}

impl<'a, K: Eq + Hash, V, S: BuildHasher + Clone> IntoIterator for &'a DashMap<K, V, S> {
type Item = RefMulti<'a, K, V, S>;
type IntoIter = Iter<'a, K, V, S, DashMap<K, V, S>>;

fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}

impl<K: Eq + Hash, V, S: BuildHasher + Clone> Extend<(K, V)> for DashMap<K, V, S> {
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, intoiter: I) {
for pair in intoiter.into_iter() {
Expand Down
3 changes: 2 additions & 1 deletion src/mapref/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>),
}
Expand Down
30 changes: 19 additions & 11 deletions src/mapref/multiple.rs
Original file line number Diff line number Diff line change
@@ -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<RwLockReadGuard<'a, HashMap<K, V, S>>>,
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<RwLockReadGuard<'a, HashMap<K, V, S>>>,
Expand Down Expand Up @@ -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)]
Expand All @@ -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<RwLockWriteGuard<'a, HashMap<K, V, S>>>,
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<RwLockWriteGuard<'a, HashMap<K, V, S>>>,
Expand Down Expand Up @@ -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)]
Expand All @@ -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()
Expand Down
5 changes: 3 additions & 2 deletions src/mapref/one.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::HashMap;
use fxhash::FxBuildHasher;
use parking_lot::{RwLockReadGuard, RwLockWriteGuard};
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
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, V, S>>,
k: &'a K,
v: &'a V,
Expand Down Expand Up @@ -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, V, S>>,
k: &'a K,
v: &'a mut V,
Expand Down

0 comments on commit 21e2184

Please sign in to comment.