Skip to content

Commit

Permalink
Bugfixes n crap. Oh and v3.4.3.
Browse files Browse the repository at this point in the history
  • Loading branch information
xacrimon committed Feb 7, 2020
1 parent 190de84 commit 867eb90
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 162 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dashmap"
version = "3.4.2"
version = "3.4.3"
authors = ["Acrimon <[email protected]>"]
edition = "2018"
license = "MIT"
Expand Down
75 changes: 0 additions & 75 deletions src/hasher.rs

This file was deleted.

11 changes: 5 additions & 6 deletions src/iter.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use super::hasher::ShardKey;
use super::mapref::multiple::{RefMulti, RefMutMulti};
use super::util;
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use crate::t::Map;
use crate::util::SharedValue;
use crate::HashMap;
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use std::collections::hash_map;
use std::hash::{BuildHasher, Hash};
use std::sync::Arc;

type GuardIter<'a, K, V, S> = (
Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>,
hash_map::Iter<'a, ShardKey<K>, SharedValue<V>>,
hash_map::Iter<'a, K, SharedValue<V>>,
);
type GuardIterMut<'a, K, V, S> = (
Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>,
hash_map::IterMut<'a, ShardKey<K>, SharedValue<V>>,
hash_map::IterMut<'a, K, SharedValue<V>>,
);

/// Iterator over a DashMap yielding immutable references.
Expand Down Expand Up @@ -64,7 +63,7 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Iterator
if let Some(current) = self.current.as_mut() {
if let Some((k, v)) = current.1.next() {
let guard = current.0.clone();
return Some(RefMulti::new(guard, k.get(), v.get()));
return Some(RefMulti::new(guard, k, v.get()));
}
}

Expand Down Expand Up @@ -132,7 +131,7 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher, M: Map<'a, K, V, S>> Iterator
unsafe {
let k = util::change_lifetime_const(k);
let v = &mut *v.as_ptr();
return Some(RefMutMulti::new(guard, k.get(), v));
return Some(RefMutMulti::new(guard, k, v));
}
}
}
Expand Down
55 changes: 16 additions & 39 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
#![allow(clippy::type_complexity)]

mod hasher;
pub mod iter;
pub mod lock;
pub mod mapref;
mod t;
mod util;
pub mod lock;

#[cfg(feature = "serde")]
mod serde;

use ahash::RandomState;
use cfg_if::cfg_if;
use hasher::{ShardBuildHasher, ShardKey};
use iter::{Iter, IterMut};
use lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use mapref::entry::{Entry, OccupiedEntry, VacantEntry};
use mapref::multiple::RefMulti;
use mapref::one::{Ref, RefMut};
use lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::borrow::Borrow;
use std::fmt;
use std::hash::Hasher;
Expand All @@ -34,7 +32,7 @@ cfg_if! {
}
}

type HashMap<K, V, S> = std::collections::HashMap<ShardKey<K>, SharedValue<V>, ShardBuildHasher<S>>;
type HashMap<K, V, S> = std::collections::HashMap<K, SharedValue<V>, S>;

#[inline]
fn shard_amount() -> usize {
Expand Down Expand Up @@ -133,17 +131,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
/// ```
#[inline]
pub fn with_hasher(hasher: S) -> Self {
let shard_amount = shard_amount();
let shift = util::ptr_size_bits() - ncb(shard_amount);
let shards = (0..shard_amount)
.map(|_| RwLock::new(HashMap::with_hasher(ShardBuildHasher::new())))
.collect();

Self {
shift,
shards,
hasher,
}
Self::with_capacity_and_hasher(0, hasher)
}

/// Creates a new DashMap with a specified starting capacity and hasher.
Expand All @@ -165,12 +153,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
let shift = util::ptr_size_bits() - ncb(shard_amount);
let cps = capacity / shard_amount;
let shards = (0..shard_amount)
.map(|_| {
RwLock::new(HashMap::with_capacity_and_hasher(
cps,
ShardBuildHasher::new(),
))
})
.map(|_| RwLock::new(HashMap::with_capacity_and_hasher(cps, hasher.clone())))
.collect();

Self {
Expand Down Expand Up @@ -569,8 +552,8 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
let idx = self.determine_shard(hash);
let mut shard = unsafe { self._yield_write_shard(idx) };
shard
.insert(ShardKey::new(key, hash as u64), SharedValue::new(value))
.map(SharedValue::into_inner)
.insert(key, SharedValue::new(value))
.map(|v| v.into_inner())
}

#[inline]
Expand All @@ -582,10 +565,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
let hash = self.hash_usize(&key);
let idx = self.determine_shard(hash);
let mut shard = unsafe { self._yield_write_shard(idx) };
let shard_key = ShardKey::new_hash(hash as u64);
shard
.remove_entry(&shard_key)
.map(|(k, v)| (k.into_inner(), v.into_inner()))
shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
}

#[inline]
Expand All @@ -607,12 +587,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
let hash = self.hash_usize(&key);
let idx = self.determine_shard(hash);
let shard = unsafe { self._yield_read_shard(idx) };
let shard_key = ShardKey::new_hash(hash as u64);
if let Some((kptr, vptr)) = shard.get_key_value(&shard_key) {
if let Some((kptr, vptr)) = shard.get_key_value(key) {
unsafe {
let kptr = util::change_lifetime_const(kptr);
let vptr = util::change_lifetime_const(vptr);
Some(Ref::new(shard, kptr.get(), vptr.get()))
Some(Ref::new(shard, kptr, vptr.get()))
}
} else {
None
Expand All @@ -628,12 +607,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
let hash = self.hash_usize(&key);
let idx = self.determine_shard(hash);
let shard = unsafe { self._yield_write_shard(idx) };
let shard_key = ShardKey::new_hash(hash as u64);
if let Some((kptr, vptr)) = shard.get_key_value(&shard_key) {
if let Some((kptr, vptr)) = shard.get_key_value(key) {
unsafe {
let kptr = util::change_lifetime_const(kptr);
let vptr = &mut *vptr.as_ptr();
Some(RefMut::new(shard, kptr.get(), vptr))
Some(RefMut::new(shard, kptr, vptr))
}
} else {
None
Expand All @@ -649,7 +627,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
fn _retain(&self, mut f: impl FnMut(&K, &mut V) -> bool) {
self.shards
.iter()
.for_each(|s| s.write().retain(|k, v| f(k.get(), v.get_mut())));
.for_each(|s| s.write().retain(|k, v| f(k, v.get_mut())));
}

#[inline]
Expand Down Expand Up @@ -678,7 +656,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
self.shards.iter().for_each(|s| {
s.write()
.iter_mut()
.for_each(|(k, v)| util::map_in_place_2((k.get(), v.get_mut()), &mut f));
.for_each(|(k, v)| util::map_in_place_2((k, v.get_mut()), &mut f));
});
}

Expand All @@ -687,12 +665,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
let hash = self.hash_usize(&key);
let idx = self.determine_shard(hash);
let shard = unsafe { self._yield_write_shard(idx) };
let shard_key = ShardKey::new_hash(hash as u64);
if let Some((kptr, vptr)) = shard.get_key_value(&shard_key) {
if let Some((kptr, vptr)) = shard.get_key_value(&key) {
unsafe {
let kptr = util::change_lifetime_const(kptr);
let vptr = &mut *vptr.as_ptr();
Entry::Occupied(OccupiedEntry::new(shard, Some(key), (kptr.get(), vptr)))
Entry::Occupied(OccupiedEntry::new(shard, Some(key), (kptr, vptr)))
}
} else {
Entry::Vacant(VacantEntry::new(shard, key))
Expand Down
49 changes: 11 additions & 38 deletions src/mapref/entry.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use super::one::RefMut;
use crate::hasher::ShardKey;
use crate::lock::RwLockWriteGuard;
use crate::util;
use crate::util::SharedValue;
use crate::HashMap;
use ahash::RandomState;
use crate::lock::RwLockWriteGuard;
use std::hash::{BuildHasher, Hash, Hasher};
use std::hash::{BuildHasher, Hash};
use std::mem;
use std::ptr;

Expand Down Expand Up @@ -88,26 +87,15 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
Self { shard, key }
}

#[inline]
fn hash_u64<T: Hash>(&self, item: &T) -> u64 {
let mut hasher = self.shard.hasher().build_hasher();
item.hash(&mut hasher);
hasher.finish()
}

#[inline]
pub fn insert(mut self, value: V) -> RefMut<'a, K, V, S> {
unsafe {
let c: K = ptr::read(&self.key);
let hash_c = self.hash_u64(&c);
let hash = self.hash_u64(&self.key);
self.shard
.insert(ShardKey::new(self.key, hash), SharedValue::new(value));
let shard_key_c = ShardKey::new_hash(hash_c);
let (k, v) = self.shard.get_key_value(&shard_key_c).unwrap();
self.shard.insert(self.key, SharedValue::new(value));
let (k, v) = self.shard.get_key_value(&c).unwrap();
let k = util::change_lifetime_const(k);
let v = &mut *v.as_ptr();
let r = RefMut::new(self.shard, k.get(), v);
let r = RefMut::new(self.shard, k, v);
mem::forget(c);
r
}
Expand Down Expand Up @@ -171,38 +159,23 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
self.elem.0
}

#[inline]
fn hash_u64<T: Hash>(&self, item: &T) -> u64 {
let mut hasher = self.shard.hasher().build_hasher();
item.hash(&mut hasher);
hasher.finish()
}

#[inline]
pub fn remove(mut self) -> V {
let hash = self.hash_u64(&self.elem.0);
let shard_key = ShardKey::new_hash(hash);
self.shard.remove(&shard_key).unwrap().into_inner()
self.shard.remove(self.elem.0).unwrap().into_inner()
}

#[inline]
pub fn remove_entry(mut self) -> (K, V) {
let hash = self.hash_u64(&self.elem.0);
let shard_key = ShardKey::new_hash(hash);
let (k, v) = self.shard.remove_entry(&shard_key).unwrap();
let (k, v) = self.shard.remove_entry(self.elem.0).unwrap();

(k.into_inner(), v.into_inner())
(k, v.into_inner())
}

#[inline]
pub fn replace_entry(mut self, value: V) -> (K, V) {
let hash = self.hash_u64(&self.elem.0);
let hash_nk = self.hash_u64(self.key.as_ref().unwrap());
let nk = self.key.unwrap();
let shard_key = ShardKey::new_hash(hash);
let (k, v) = self.shard.remove_entry(&shard_key).unwrap();
self.shard
.insert(ShardKey::new(nk, hash_nk), SharedValue::new(value));
(k.into_inner(), v.into_inner())
let (k, v) = self.shard.remove_entry(self.elem.0).unwrap();
self.shard.insert(nk, SharedValue::new(value));
(k, v.into_inner())
}
}
2 changes: 1 addition & 1 deletion src/mapref/multiple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use crate::HashMap;
use ahash::RandomState;
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use std::hash::BuildHasher;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
Expand Down
2 changes: 1 addition & 1 deletion src/mapref/one.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use crate::HashMap;
use ahash::RandomState;
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use std::hash::{BuildHasher, Hash};
use std::ops::{Deref, DerefMut};

Expand Down
2 changes: 1 addition & 1 deletion src/t.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! Central map trait to ease modifications and extensions down the road.
use crate::iter::{Iter, IterMut};
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use crate::mapref::entry::Entry;
use crate::mapref::one::{Ref, RefMut};
use crate::HashMap;
use crate::lock::{RwLockReadGuard, RwLockWriteGuard};
use std::borrow::Borrow;
use std::hash::{BuildHasher, Hash};

Expand Down

0 comments on commit 867eb90

Please sign in to comment.