mirror of https://github.com/xacrimon/dashmap
Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Joel Wejdenstål | 626b98dab3 | |
Joel | 1e7efe5843 | |
Joel Wejdenstål | eff796d46b | |
Joel Wejdenstål | febc45dc62 |
|
@ -71,7 +71,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.1"
|
||||
version = "5.5.3"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"cfg-if",
|
||||
|
@ -212,18 +212,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.185"
|
||||
version = "1.0.188"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.185"
|
||||
version = "1.0.188"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "dashmap"
|
||||
version = "5.5.1"
|
||||
version = "5.5.3"
|
||||
authors = ["Acrimon <joel.wejdenstal@gmail.com>"]
|
||||
edition = "2018"
|
||||
rust-version = "1.64"
|
||||
rust-version = "1.65"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/xacrimon/dashmap"
|
||||
homepage = "https://github.com/xacrimon/dashmap"
|
||||
|
@ -21,7 +21,7 @@ inline = ["hashbrown/inline-more"]
|
|||
lock_api = "0.4.10"
|
||||
parking_lot_core = "0.9.8"
|
||||
hashbrown = { version = "0.14.0", default-features = false }
|
||||
serde = { version = "1.0.171", optional = true, features = ["derive"] }
|
||||
serde = { version = "1.0.188", optional = true, features = ["derive"] }
|
||||
cfg-if = "1.0.0"
|
||||
rayon = { version = "1.7.0", optional = true }
|
||||
once_cell = "1.18.0"
|
||||
|
|
|
@ -20,7 +20,7 @@ If you have any suggestions or tips do not hesitate to open an issue or a PR.
|
|||
|
||||
[![downloads](https://img.shields.io/crates/d/dashmap)](https://crates.io/crates/dashmap)
|
||||
|
||||
[![minimum rustc version](https://img.shields.io/badge/rustc-1.64-orange.svg)](https://crates.io/crates/dashmap)
|
||||
[![minimum rustc version](https://img.shields.io/badge/rustc-1.65-orange.svg)](https://crates.io/crates/dashmap)
|
||||
|
||||
## Cargo features
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "stable-2022-09-22"
|
||||
channel = "1.65"
|
||||
components = ["rustfmt", "clippy"]
|
||||
profile = "minimal"
|
||||
|
|
104
src/lib.rs
104
src/lib.rs
|
@ -34,7 +34,6 @@ use core::fmt;
|
|||
use core::hash::{BuildHasher, Hash, Hasher};
|
||||
use core::iter::FromIterator;
|
||||
use core::ops::{BitAnd, BitOr, Shl, Shr, Sub};
|
||||
use hashbrown::hash_map::RawEntryMut;
|
||||
use iter::{Iter, IterMut, OwningIter};
|
||||
use mapref::entry::{Entry, OccupiedEntry, VacantEntry};
|
||||
use mapref::multiple::RefMulti;
|
||||
|
@ -296,15 +295,11 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// Hash a given item to produce a usize.
|
||||
/// Uses the provided or default HashBuilder.
|
||||
pub fn hash_usize<T: Hash>(&self, item: &T) -> usize {
|
||||
self.hash_u64(item) as usize
|
||||
}
|
||||
|
||||
fn hash_u64<T: Hash>(&self, item: &T) -> u64 {
|
||||
let mut hasher = self.hasher.build_hasher();
|
||||
|
||||
item.hash(&mut hasher);
|
||||
|
||||
hasher.finish()
|
||||
hasher.finish() as usize
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
|
@ -921,9 +916,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
}
|
||||
|
||||
fn _insert(&self, key: K, value: V) -> Option<V> {
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let mut shard = unsafe { self._yield_write_shard(idx) };
|
||||
|
||||
|
@ -937,9 +932,9 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let mut shard = unsafe { self._yield_write_shard(idx) };
|
||||
|
||||
|
@ -951,20 +946,22 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let mut shard = unsafe { self._yield_write_shard(idx) };
|
||||
|
||||
if let RawEntryMut::Occupied(entry) =
|
||||
shard.raw_entry_mut().from_key_hashed_nocheck(hash, key)
|
||||
{
|
||||
if f(entry.key(), entry.get().get()) {
|
||||
let (k, v) = entry.remove_entry();
|
||||
Some((k, v.into_inner()))
|
||||
} else {
|
||||
None
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *mut V = vptr.as_ptr();
|
||||
|
||||
if f(&*kptr, &mut *vptr) {
|
||||
shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
@ -976,21 +973,22 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let mut shard = unsafe { self._yield_write_shard(idx) };
|
||||
|
||||
if let RawEntryMut::Occupied(mut entry) =
|
||||
shard.raw_entry_mut().from_key_hashed_nocheck(hash, key)
|
||||
{
|
||||
let (k, v) = entry.get_key_value_mut();
|
||||
if f(k, v.get_mut()) {
|
||||
let (k, v) = entry.remove_entry();
|
||||
Some((k, v.into_inner()))
|
||||
} else {
|
||||
None
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *mut V = vptr.as_ptr();
|
||||
|
||||
if f(&*kptr, &mut *vptr) {
|
||||
shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
@ -1010,13 +1008,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self._yield_read_shard(idx) };
|
||||
|
||||
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) {
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *const V = vptr.get();
|
||||
|
@ -1032,18 +1030,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let mut shard = unsafe { self._yield_write_shard(idx) };
|
||||
let shard = unsafe { self._yield_write_shard(idx) };
|
||||
|
||||
if let RawEntryMut::Occupied(mut entry) =
|
||||
shard.raw_entry_mut().from_key_hashed_nocheck(hash, key)
|
||||
{
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(key) {
|
||||
unsafe {
|
||||
let kptr: *const K = entry.key();
|
||||
let vptr: *mut V = entry.get_mut().as_ptr();
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *mut V = vptr.as_ptr();
|
||||
Some(RefMut::new(shard, kptr, vptr))
|
||||
}
|
||||
} else {
|
||||
|
@ -1056,16 +1052,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let shard = match unsafe { self._try_yield_read_shard(idx) } {
|
||||
Some(shard) => shard,
|
||||
None => return TryResult::Locked,
|
||||
};
|
||||
|
||||
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) {
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *const V = vptr.get();
|
||||
|
@ -1081,16 +1077,16 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let shard = match unsafe { self._try_yield_write_shard(idx) } {
|
||||
Some(shard) => shard,
|
||||
None => return TryResult::Locked,
|
||||
};
|
||||
|
||||
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, key) {
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *mut V = vptr.as_ptr();
|
||||
|
@ -1149,13 +1145,13 @@ 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> {
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self._yield_write_shard(idx) };
|
||||
|
||||
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) {
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(&key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *mut V = vptr.as_ptr();
|
||||
|
@ -1167,16 +1163,16 @@ 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<Entry<'a, K, V, S>> {
|
||||
let hash = self.hash_u64(&key);
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
let idx = self.determine_shard(hash as usize);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
||||
let shard = match unsafe { self._try_yield_write_shard(idx) } {
|
||||
Some(shard) => shard,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
if let Some((kptr, vptr)) = shard.raw_entry().from_key_hashed_nocheck(hash, &key) {
|
||||
if let Some((kptr, vptr)) = shard.get_key_value(&key) {
|
||||
unsafe {
|
||||
let kptr: *const K = kptr;
|
||||
let vptr: *mut V = vptr.as_ptr();
|
||||
|
|
|
@ -61,7 +61,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.get(key).is_some()
|
||||
let hash = self.map.hash_usize(&key);
|
||||
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
|
||||
shard.contains_key(key)
|
||||
}
|
||||
|
||||
/// Returns a reference to the value corresponding to the key.
|
||||
|
@ -70,7 +76,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.get_key_value(key).map(|(_k, v)| v)
|
||||
let hash = self.map.hash_usize(&key);
|
||||
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
|
||||
shard.get(key).map(|v| v.get())
|
||||
}
|
||||
|
||||
/// Returns the key-value pair corresponding to the supplied key.
|
||||
|
@ -79,16 +91,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S>
|
|||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_u64(&key);
|
||||
let hash = self.map.hash_usize(&key);
|
||||
|
||||
let idx = self.map.determine_shard(hash as usize);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
|
||||
shard
|
||||
.raw_entry()
|
||||
.from_key_hashed_nocheck(hash, key)
|
||||
.map(|(k, v)| (k, v.get()))
|
||||
shard.get_key_value(key).map(|(k, v)| (k, v.get()))
|
||||
}
|
||||
|
||||
fn shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a {
|
||||
|
|
Loading…
Reference in New Issue