Skip to content

Commit

Permalink
Merge branch 'small-optimizations' of github.com:arthurprs/dashmap in…
Browse files Browse the repository at this point in the history
…to arthurprs-small-optimizations
  • Loading branch information
xacrimon committed Jun 17, 2024
2 parents 4be6f57 + 0f95f59 commit 74b34f8
Show file tree
Hide file tree
Showing 18 changed files with 412 additions and 440 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ inline = ["hashbrown/inline-more"]
[dependencies]
lock_api = "0.4.10"
parking_lot_core = "0.9.8"
hashbrown = { version = "0.14.0", default-features = false }
hashbrown = { version = "0.14.0", default-features = false, features = ["raw"] }
serde = { version = "1.0.188", optional = true, features = ["derive"] }
cfg-if = "1.0.0"
rayon = { version = "1.7.0", optional = true }
Expand Down
71 changes: 33 additions & 38 deletions src/iter.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use super::mapref::multiple::{RefMulti, RefMutMulti};
use super::util;
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;
use std::marker::PhantomData;
use std::sync::Arc;

/// Iterator over a DashMap yielding key value pairs.
Expand Down Expand Up @@ -39,7 +38,7 @@ impl<K: Eq + Hash, V, S: BuildHasher + Clone> OwningIter<K, V, S> {
}
}

type GuardOwningIter<K, V> = hash_map::IntoIter<K, SharedValue<V>>;
type GuardOwningIter<K, V> = hashbrown::raw::RawIntoIter<(K, SharedValue<V>)>;

impl<K: Eq + Hash, V, S: BuildHasher + Clone> Iterator for OwningIter<K, V, S> {
type Item = (K, V);
Expand All @@ -59,9 +58,7 @@ impl<K: Eq + Hash, V, S: BuildHasher + Clone> Iterator for OwningIter<K, V, S> {
//let guard = unsafe { self.map._yield_read_shard(self.shard_i) };
let mut shard_wl = unsafe { self.map._yield_write_shard(self.shard_i) };

let hasher = self.map._hasher();

let map = mem::replace(&mut *shard_wl, HashMap::with_hasher(hasher));
let map = mem::take(&mut *shard_wl);

drop(shard_wl);

Expand Down Expand Up @@ -91,14 +88,14 @@ where
{
}

type GuardIter<'a, K, V, S> = (
Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>,
hash_map::Iter<'a, K, SharedValue<V>>,
type GuardIter<'a, K, V> = (
Arc<RwLockReadGuard<'a, HashMap<K, V>>>,
hashbrown::raw::RawIter<(K, SharedValue<V>)>,
);

type GuardIterMut<'a, K, V, S> = (
Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>,
hash_map::IterMut<'a, K, SharedValue<V>>,
type GuardIterMut<'a, K, V> = (
Arc<RwLockWriteGuard<'a, HashMap<K, V>>>,
hashbrown::raw::RawIter<(K, SharedValue<V>)>,
);

/// Iterator over a DashMap yielding immutable references.
Expand All @@ -115,7 +112,8 @@ type GuardIterMut<'a, K, V, S> = (
pub struct Iter<'a, K, V, S = RandomState, M = DashMap<K, V, S>> {
map: &'a M,
shard_i: usize,
current: Option<GuardIter<'a, K, V, S>>,
current: Option<GuardIter<'a, K, V>>,
marker: PhantomData<S>,
}

impl<'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter<'i, K, V, S> {
Expand Down Expand Up @@ -148,22 +146,25 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter
map,
shard_i: 0,
current: None,
marker: PhantomData,
}
}
}

impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator
for Iter<'a, K, V, S, M>
{
type Item = RefMulti<'a, K, V, S>;
type Item = RefMulti<'a, K, V>;

fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(current) = self.current.as_mut() {
if let Some((k, v)) = current.1.next() {
let guard = current.0.clone();

return unsafe { Some(RefMulti::new(guard, k, v.get())) };
if let Some(b) = current.1.next() {
return unsafe {
let (k, v) = b.as_ref();
let guard = current.0.clone();
Some(RefMulti::new(guard, k, v.get()))
};
}
}

Expand All @@ -173,9 +174,7 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter

let guard = unsafe { self.map._yield_read_shard(self.shard_i) };

let sref: &HashMap<K, V, S> = unsafe { util::change_lifetime_const(&*guard) };

let iter = sref.iter();
let iter = unsafe { guard.iter() };

self.current = Some((Arc::new(guard), iter));

Expand All @@ -199,7 +198,8 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter
pub struct IterMut<'a, K, V, S = RandomState, M = DashMap<K, V, S>> {
map: &'a M,
shard_i: usize,
current: Option<GuardIterMut<'a, K, V, S>>,
current: Option<GuardIterMut<'a, K, V>>,
marker: PhantomData<S>,
}

unsafe impl<'a, 'i, K, V, S, M> Send for IterMut<'i, K, V, S, M>
Expand Down Expand Up @@ -228,40 +228,35 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>>
map,
shard_i: 0,
current: None,
marker: PhantomData,
}
}
}

impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator
for IterMut<'a, K, V, S, M>
{
type Item = RefMutMulti<'a, K, V, S>;
type Item = RefMutMulti<'a, K, V>;

fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(current) = self.current.as_mut() {
if let Some((k, v)) = current.1.next() {
let guard = current.0.clone();

unsafe {
let k = util::change_lifetime_const(k);

let v = &mut *v.as_ptr();

return Some(RefMutMulti::new(guard, k, v));
}
if let Some(b) = current.1.next() {
return unsafe {
let (k, v) = b.as_mut();
let guard = current.0.clone();
Some(RefMutMulti::new(guard, k, v.get_mut()))
};
}
}

if self.shard_i == self.map._shard_count() {
return None;
}

let mut guard = unsafe { self.map._yield_write_shard(self.shard_i) };

let sref: &mut HashMap<K, V, S> = unsafe { util::change_lifetime_mut(&mut *guard) };
let guard = unsafe { self.map._yield_write_shard(self.shard_i) };

let iter = sref.iter_mut();
let iter = unsafe { guard.iter() };

self.current = Some((Arc::new(guard), iter));

Expand All @@ -285,7 +280,7 @@ mod tests {
let mut c = 0;

for shard in map.shards() {
c += shard.write().iter_mut().count();
c += unsafe { shard.write().iter().count() };
}

assert_eq!(c, 1);
Expand Down
2 changes: 1 addition & 1 deletion src/iter_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<'a, K: Eq + Hash, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iter<'
impl<'a, K: Eq + Hash, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iterator
for Iter<'a, K, S, M>
{
type Item = RefMulti<'a, K, S>;
type Item = RefMulti<'a, K>;

fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(RefMulti::new)
Expand Down
Loading

0 comments on commit 74b34f8

Please sign in to comment.