1
+ use crossbeam_utils:: CachePadded ;
1
2
use hashbrown:: hash_table;
2
3
3
4
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 ;
11
8
use std:: sync:: Arc ;
12
9
13
10
/// Iterator over a DashMap yielding key value pairs.
@@ -23,25 +20,23 @@ use std::sync::Arc;
23
20
/// let pairs: Vec<(&'static str, &'static str)> = map.into_iter().collect();
24
21
/// assert_eq!(pairs.len(), 2);
25
22
/// ```
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 > > > > ,
29
25
current : Option < GuardOwningIter < K , V > > ,
30
26
}
31
27
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 {
34
30
Self {
35
- map,
36
- shard_i : 0 ,
31
+ shards : map. shards . into_vec ( ) . into_iter ( ) ,
37
32
current : None ,
38
33
}
39
34
}
40
35
}
41
36
42
37
type GuardOwningIter < K , V > = hash_table:: IntoIter < ( K , V ) > ;
43
38
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 > {
45
40
type Item = ( K , V ) ;
46
41
47
42
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> {
52
47
}
53
48
}
54
49
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 ( ) ;
67
51
self . current = Some ( iter) ;
68
-
69
- self . shard_i += 1 ;
70
52
}
71
53
}
72
54
}
@@ -92,62 +74,49 @@ type GuardIterMut<'a, K, V> = (
92
74
/// map.insert("hello", "world");
93
75
/// assert_eq!(map.iter().count(), 1);
94
76
/// ```
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 > > > > ,
98
79
current : Option < GuardIter < ' a , K , V > > ,
99
- marker : PhantomData < S > ,
100
80
}
101
81
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 > {
103
83
fn clone ( & self ) -> Self {
104
- Iter :: new ( self . map )
84
+ Iter {
85
+ shards : self . shards . clone ( ) ,
86
+ current : self . current . clone ( ) ,
87
+ }
105
88
}
106
89
}
107
90
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 {
112
93
Self {
113
- map,
114
- shard_i : 0 ,
94
+ shards : map. shards . iter ( ) ,
115
95
current : None ,
116
- marker : PhantomData ,
117
96
}
118
97
}
119
98
}
120
99
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 > {
124
101
type Item = RefMulti < ' a , K , V > ;
125
102
126
103
fn next ( & mut self ) -> Option < Self :: Item > {
127
104
loop {
128
105
if let Some ( current) = self . current . as_mut ( ) {
129
106
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) ) ;
134
109
}
135
110
}
136
111
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 ( ) ;
142
113
// SAFETY: we keep the guard alive with the shard iterator,
143
114
// and with any refs produced by the iterator
144
115
let ( guard, shard) = unsafe { RwLockReadGuardDetached :: detach_from ( guard) } ;
145
116
146
117
let iter = shard. iter ( ) ;
147
118
148
119
self . current = Some ( ( Arc :: new ( guard) , iter) ) ;
149
-
150
- self . shard_i += 1 ;
151
120
}
152
121
}
153
122
}
@@ -164,47 +133,33 @@ impl<'a, K: Eq + Hash + 'a, V: 'a, S: 'a + BuildHasher + Clone, M: Map<'a, K, V,
164
133
/// map.iter_mut().for_each(|mut r| *r += 1);
165
134
/// assert_eq!(*map.get("Johnny").unwrap(), 22);
166
135
/// ```
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 > > > > ,
170
138
current : Option < GuardIterMut < ' a , K , V > > ,
171
- marker : PhantomData < S > ,
172
139
}
173
140
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 {
178
143
Self {
179
- map,
180
- shard_i : 0 ,
144
+ shards : map. shards . iter ( ) ,
181
145
current : None ,
182
- marker : PhantomData ,
183
146
}
184
147
}
185
148
}
186
149
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 > {
190
151
type Item = RefMutMulti < ' a , K , V > ;
191
152
192
153
fn next ( & mut self ) -> Option < Self :: Item > {
193
154
loop {
194
155
if let Some ( current) = self . current . as_mut ( ) {
195
156
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) ) ;
200
159
}
201
160
}
202
161
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 ( ) ;
208
163
209
164
// SAFETY: we keep the guard alive with the shard iterator,
210
165
// 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,
213
168
let iter = shard. iter_mut ( ) ;
214
169
215
170
self . current = Some ( ( Arc :: new ( guard) , iter) ) ;
216
-
217
- self . shard_i += 1 ;
218
171
}
219
172
}
220
173
}
0 commit comments