Skip to content

Commit 55f7cdf

Browse files
misc unsafe removals (#325)
* misc: remove unsafe from shard handling via unreachable assertion * breaking: remove Map trait * remove hasher from iterators * remove unnecessary unsafe markers and remove some dead functions
1 parent 54710a6 commit 55f7cdf

File tree

11 files changed

+156
-351
lines changed

11 files changed

+156
-351
lines changed

src/iter.rs

+34-81
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1+
use crossbeam_utils::CachePadded;
12
use hashbrown::hash_table;
23

34
use super::mapref::multiple::{RefMulti, RefMutMulti};
4-
use crate::lock::{RwLockReadGuardDetached, RwLockWriteGuardDetached};
5-
use crate::t::Map;
6-
use crate::DashMap;
7-
use core::hash::{BuildHasher, Hash};
8-
use core::mem;
9-
use std::collections::hash_map::RandomState;
10-
use std::marker::PhantomData;
5+
use crate::lock::{RwLock, RwLockReadGuardDetached, RwLockWriteGuardDetached};
6+
use crate::{DashMap, HashMap};
7+
use core::hash::Hash;
118
use std::sync::Arc;
129

1310
/// Iterator over a DashMap yielding key value pairs.
@@ -23,25 +20,23 @@ use std::sync::Arc;
2320
/// let pairs: Vec<(&'static str, &'static str)> = map.into_iter().collect();
2421
/// assert_eq!(pairs.len(), 2);
2522
/// ```
26-
pub struct OwningIter<K, V, S = RandomState> {
27-
map: DashMap<K, V, S>,
28-
shard_i: usize,
23+
pub struct OwningIter<K, V> {
24+
shards: std::vec::IntoIter<CachePadded<RwLock<HashMap<K, V>>>>,
2925
current: Option<GuardOwningIter<K, V>>,
3026
}
3127

32-
impl<K: Eq + Hash, V, S: BuildHasher + Clone> OwningIter<K, V, S> {
33-
pub(crate) fn new(map: DashMap<K, V, S>) -> Self {
28+
impl<K: Eq + Hash, V> OwningIter<K, V> {
29+
pub(crate) fn new<S>(map: DashMap<K, V, S>) -> Self {
3430
Self {
35-
map,
36-
shard_i: 0,
31+
shards: map.shards.into_vec().into_iter(),
3732
current: None,
3833
}
3934
}
4035
}
4136

4237
type GuardOwningIter<K, V> = hash_table::IntoIter<(K, V)>;
4338

44-
impl<K: Eq + Hash, V, S: BuildHasher + Clone> Iterator for OwningIter<K, V, S> {
39+
impl<K: Eq + Hash, V> Iterator for OwningIter<K, V> {
4540
type Item = (K, V);
4641

4742
fn next(&mut self) -> Option<Self::Item> {
@@ -52,21 +47,8 @@ impl<K: Eq + Hash, V, S: BuildHasher + Clone> Iterator for OwningIter<K, V, S> {
5247
}
5348
}
5449

55-
if self.shard_i == self.map._shard_count() {
56-
return None;
57-
}
58-
59-
let mut shard_wl = unsafe { self.map._yield_write_shard(self.shard_i) };
60-
61-
let map = mem::take(&mut *shard_wl);
62-
63-
drop(shard_wl);
64-
65-
let iter = map.into_iter();
66-
50+
let iter = self.shards.next()?.into_inner().into_inner().into_iter();
6751
self.current = Some(iter);
68-
69-
self.shard_i += 1;
7052
}
7153
}
7254
}
@@ -92,62 +74,49 @@ type GuardIterMut<'a, K, V> = (
9274
/// map.insert("hello", "world");
9375
/// assert_eq!(map.iter().count(), 1);
9476
/// ```
95-
pub struct Iter<'a, K, V, S = RandomState, M = DashMap<K, V, S>> {
96-
map: &'a M,
97-
shard_i: usize,
77+
pub struct Iter<'a, K, V> {
78+
shards: std::slice::Iter<'a, CachePadded<RwLock<HashMap<K, V>>>>,
9879
current: Option<GuardIter<'a, K, V>>,
99-
marker: PhantomData<S>,
10080
}
10181

102-
impl<'i, K: Clone + Hash + Eq, V: Clone, S: Clone + BuildHasher> Clone for Iter<'i, K, V, S> {
82+
impl<'i, K: Clone + Hash + Eq, V: Clone> Clone for Iter<'i, K, V> {
10383
fn clone(&self) -> Self {
104-
Iter::new(self.map)
84+
Iter {
85+
shards: self.shards.clone(),
86+
current: self.current.clone(),
87+
}
10588
}
10689
}
10790

108-
impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>>
109-
Iter<'a, K, V, S, M>
110-
{
111-
pub(crate) fn new(map: &'a M) -> Self {
91+
impl<'a, K: Eq + Hash + 'a, V: 'a> Iter<'a, K, V> {
92+
pub(crate) fn new<S>(map: &'a DashMap<K, V, S>) -> Self {
11293
Self {
113-
map,
114-
shard_i: 0,
94+
shards: map.shards.iter(),
11595
current: None,
116-
marker: PhantomData,
11796
}
11897
}
11998
}
12099

121-
impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator
122-
for Iter<'a, K, V, S, M>
123-
{
100+
impl<'a, K: Eq + Hash + 'a, V: 'a> Iterator for Iter<'a, K, V> {
124101
type Item = RefMulti<'a, K, V>;
125102

126103
fn next(&mut self) -> Option<Self::Item> {
127104
loop {
128105
if let Some(current) = self.current.as_mut() {
129106
if let Some((k, v)) = current.1.next() {
130-
return unsafe {
131-
let guard = current.0.clone();
132-
Some(RefMulti::new(guard, k, v))
133-
};
107+
let guard = current.0.clone();
108+
return Some(RefMulti::new(guard, k, v));
134109
}
135110
}
136111

137-
if self.shard_i == self.map._shard_count() {
138-
return None;
139-
}
140-
141-
let guard = unsafe { self.map._yield_read_shard(self.shard_i) };
112+
let guard = self.shards.next()?.read();
142113
// SAFETY: we keep the guard alive with the shard iterator,
143114
// and with any refs produced by the iterator
144115
let (guard, shard) = unsafe { RwLockReadGuardDetached::detach_from(guard) };
145116

146117
let iter = shard.iter();
147118

148119
self.current = Some((Arc::new(guard), iter));
149-
150-
self.shard_i += 1;
151120
}
152121
}
153122
}
@@ -164,47 +133,33 @@ impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V,
164133
/// map.iter_mut().for_each(|mut r| *r += 1);
165134
/// assert_eq!(*map.get("Johnny").unwrap(), 22);
166135
/// ```
167-
pub struct IterMut<'a, K, V, S = RandomState, M = DashMap<K, V, S>> {
168-
map: &'a M,
169-
shard_i: usize,
136+
pub struct IterMut<'a, K, V> {
137+
shards: std::slice::Iter<'a, CachePadded<RwLock<HashMap<K, V>>>>,
170138
current: Option<GuardIterMut<'a, K, V>>,
171-
marker: PhantomData<S>,
172139
}
173140

174-
impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>>
175-
IterMut<'a, K, V, S, M>
176-
{
177-
pub(crate) fn new(map: &'a M) -> Self {
141+
impl<'a, K: Eq + Hash + 'a, V: 'a> IterMut<'a, K, V> {
142+
pub(crate) fn new<S>(map: &'a DashMap<K, V, S>) -> Self {
178143
Self {
179-
map,
180-
shard_i: 0,
144+
shards: map.shards.iter(),
181145
current: None,
182-
marker: PhantomData,
183146
}
184147
}
185148
}
186149

187-
impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iterator
188-
for IterMut<'a, K, V, S, M>
189-
{
150+
impl<'a, K: Eq + Hash + 'a, V: 'a> Iterator for IterMut<'a, K, V> {
190151
type Item = RefMutMulti<'a, K, V>;
191152

192153
fn next(&mut self) -> Option<Self::Item> {
193154
loop {
194155
if let Some(current) = self.current.as_mut() {
195156
if let Some((k, v)) = current.1.next() {
196-
return unsafe {
197-
let guard = current.0.clone();
198-
Some(RefMutMulti::new(guard, k, v))
199-
};
157+
let guard = current.0.clone();
158+
return Some(RefMutMulti::new(guard, k, v));
200159
}
201160
}
202161

203-
if self.shard_i == self.map._shard_count() {
204-
return None;
205-
}
206-
207-
let guard = unsafe { self.map._yield_write_shard(self.shard_i) };
162+
let guard = self.shards.next()?.write();
208163

209164
// SAFETY: we keep the guard alive with the shard iterator,
210165
// and with any refs produced by the iterator
@@ -213,8 +168,6 @@ impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V,
213168
let iter = shard.iter_mut();
214169

215170
self.current = Some((Arc::new(guard), iter));
216-
217-
self.shard_i += 1;
218171
}
219172
}
220173
}

src/iter_set.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,35 @@
11
use crate::setref::multiple::RefMulti;
2-
use crate::t::Map;
3-
use core::hash::{BuildHasher, Hash};
2+
use core::hash::Hash;
43

5-
pub struct OwningIter<K, S> {
6-
inner: crate::iter::OwningIter<K, (), S>,
4+
pub struct OwningIter<K> {
5+
inner: crate::iter::OwningIter<K, ()>,
76
}
87

9-
impl<K: Eq + Hash, S: BuildHasher + Clone> OwningIter<K, S> {
10-
pub(crate) fn new(inner: crate::iter::OwningIter<K, (), S>) -> Self {
8+
impl<K: Eq + Hash> OwningIter<K> {
9+
pub(crate) fn new(inner: crate::iter::OwningIter<K, ()>) -> Self {
1110
Self { inner }
1211
}
1312
}
1413

15-
impl<K: Eq + Hash, S: BuildHasher + Clone> Iterator for OwningIter<K, S> {
14+
impl<K: Eq + Hash> Iterator for OwningIter<K> {
1615
type Item = K;
1716

1817
fn next(&mut self) -> Option<Self::Item> {
1918
self.inner.next().map(|(k, _)| k)
2019
}
2120
}
2221

23-
pub struct Iter<'a, K, S, M> {
24-
inner: crate::iter::Iter<'a, K, (), S, M>,
22+
pub struct Iter<'a, K> {
23+
inner: crate::iter::Iter<'a, K, ()>,
2524
}
2625

27-
impl<'a, K: Eq + Hash + 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iter<'a, K, S, M> {
28-
pub(crate) fn new(inner: crate::iter::Iter<'a, K, (), S, M>) -> Self {
26+
impl<'a, K: Eq + Hash + 'a> Iter<'a, K> {
27+
pub(crate) fn new(inner: crate::iter::Iter<'a, K, ()>) -> Self {
2928
Self { inner }
3029
}
3130
}
3231

33-
impl<'a, K: Eq + Hash + 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iterator
34-
for Iter<'a, K, S, M>
35-
{
32+
impl<'a, K: Eq + Hash + 'a> Iterator for Iter<'a, K> {
3633
type Item = RefMulti<'a, K>;
3734

3835
fn next(&mut self) -> Option<Self::Item> {

0 commit comments

Comments
 (0)