@@ -17,13 +17,12 @@ use cmp;
17
17
use hash:: { Hash , Hasher } ;
18
18
use iter:: { Iterator , IteratorExt , ExactSizeIterator , count} ;
19
19
use marker:: { Copy , Sized } ;
20
- use mem:: { min_align_of, size_of} ;
21
- use mem;
20
+ use mem:: { self , min_align_of, size_of} ;
22
21
use num:: { Int , UnsignedInt } ;
23
22
use ops:: { Deref , DerefMut , Drop } ;
24
- use option:: Option ;
25
- use option:: Option :: { Some , None } ;
23
+ use option:: Option :: { self , Some , None } ;
26
24
use ptr:: { self , Unique , PtrExt , copy_memory, copy_nonoverlapping_memory, zero_memory} ;
25
+ use result:: Result :: { self , Ok , Err } ;
27
26
use rt:: heap:: { allocate, deallocate, reallocate_inplace} ;
28
27
use collections:: hash_state:: HashState ;
29
28
use core:: nonzero:: NonZero ;
@@ -95,6 +94,7 @@ impl<K,V,M:Copy,S> Copy for Bucket<K,V,M,S> {}
95
94
mod bucket {
96
95
pub enum Empty { }
97
96
pub enum Full { }
97
+ pub enum TableIsEmpty { }
98
98
}
99
99
100
100
pub type EmptyBucket < K , V , M > = Bucket < K , V , M , bucket:: Empty > ;
@@ -151,6 +151,14 @@ fn can_alias_safehash_as_option() {
151
151
assert_eq ! ( size_of:: <SafeHash >( ) , size_of:: <Option <SafeHash >>( ) )
152
152
}
153
153
154
+ impl < K , V > Deref for RawTable < K , V > {
155
+ type Target = RawTable < K , V > ;
156
+
157
+ fn deref ( & self ) -> & RawTable < K , V > {
158
+ self
159
+ }
160
+ }
161
+
154
162
impl < K , V , M > RawBucket < K , V , M > {
155
163
unsafe fn offset ( self , count : int ) -> RawBucket < K , V , M > {
156
164
RawBucket {
@@ -210,29 +218,47 @@ impl<K, V, M, S> Bucket<K, V, M, S> {
210
218
pub fn index ( & self ) -> uint {
211
219
self . 0 . idx
212
220
}
221
+ /// Turn the bucket into an iterator over full buckets.
222
+ pub fn into_iter ( self ) -> RawFullBuckets < K , V , M > {
223
+ RawFullBuckets {
224
+ raw : self . raw ,
225
+ hashes_end : unsafe {
226
+ self . raw . hash . offset ( self . 0 . capacity as int - self . index ( ) as int )
227
+ } ,
228
+ table : self . table ,
229
+ }
230
+ }
213
231
}
214
232
215
233
impl < K , V , M : Deref < Target =RawTable < K , V > > > Bucket < K , V , M > {
216
234
pub fn new ( table : M , hash : SafeHash ) -> Option < Bucket < K , V , M > > {
217
- Bucket :: at_index ( table, * hash as usize )
235
+ Bucket :: at_index ( table, * hash as usize ) . ok ( )
218
236
}
219
237
220
- pub fn at_index ( table : M , ib_index : uint ) -> Option < Bucket < K , V , M > > {
238
+ pub fn at_index ( table : M , ib_index : uint )
239
+ -> Result < Bucket < K , V , M > , Bucket < K , V , M , bucket:: TableIsEmpty > >
240
+ {
241
+ let ib_index = ib_index & ( table. capacity ( ) - 1 ) ;
242
+ let bb = BareBucket {
243
+ raw : unsafe {
244
+ table. first_bucket_raw ( ) . offset ( ib_index as int )
245
+ } ,
246
+ idx : ib_index,
247
+ capacity : table. capacity ( ) ,
248
+ table : table,
249
+ } ;
250
+
221
251
if table. capacity ( ) == 0 {
222
- None
252
+ Err ( Bucket ( bb ) )
223
253
} else {
224
- let ib_index = ib_index & ( table. capacity ( ) - 1 ) ;
225
- Some ( Bucket ( BareBucket {
226
- raw : unsafe {
227
- table. first_bucket_raw ( ) . offset ( ib_index as int )
228
- } ,
229
- idx : ib_index,
230
- capacity : table. capacity ( ) ,
231
- table : table
232
- } ) )
254
+ Ok ( Bucket ( bb) )
233
255
}
234
256
}
235
257
258
+ pub fn raw_full_buckets ( table : M ) -> RawFullBuckets < K , V , M > {
259
+ Bucket :: at_index ( table, 0 ) . map ( |b| b. into_iter ( ) ) . unwrap_or_else ( |b| b. into_iter ( ) )
260
+ }
261
+
236
262
/// Narrows down the range of iteration, which must be a power of 2.
237
263
pub fn iter_to ( mut self , limit : usize ) -> Bucket < K , V , M > {
238
264
assert ! ( limit <= self . capacity) ;
@@ -461,7 +487,7 @@ impl<K, V> RawTable<K, V> {
461
487
}
462
488
463
489
#[ inline]
464
- fn first_bucket_raw < M > ( & self ) -> RawBucket < K , V , M > {
490
+ unsafe fn first_bucket_raw < M > ( & self ) -> RawBucket < K , V , M > {
465
491
if self . capacity ( ) == 0 {
466
492
RawBucket {
467
493
hash : ptr:: null_mut ( ) ,
@@ -539,18 +565,10 @@ impl<K, V> RawTable<K, V> {
539
565
self . size
540
566
}
541
567
542
- pub fn raw_full_buckets ( & self ) -> RawFullBuckets < K , V , & RawTable < K , V > > {
543
- full_buckets ( self . first_bucket_raw ( ) , self . capacity , self )
544
- }
545
-
546
- pub fn raw_full_buckets_mut ( & mut self ) -> RawFullBuckets < K , V , & mut RawTable < K , V > > {
547
- full_buckets ( self . first_bucket_raw ( ) , self . capacity , self )
548
- }
549
-
550
568
pub fn into_iter ( self ) -> IntoIter < K , V > {
551
569
// Replace the marker regardless of lifetime bounds on parameters.
552
570
IntoIter {
553
- iter : full_buckets ( self . first_bucket_raw ( ) , self . capacity , self )
571
+ iter : Bucket :: raw_full_buckets ( self ) ,
554
572
}
555
573
}
556
574
}
@@ -596,14 +614,7 @@ fn align<K, V>() -> usize {
596
614
cmp:: max ( mem:: min_align_of :: < ( K , V ) > ( ) , mem:: min_align_of :: < u64 > ( ) )
597
615
}
598
616
599
- pub fn full_buckets < K , V , M > ( raw : RawBucket < K , V , M > , cap : usize , t : M ) -> RawFullBuckets < K , V , M > {
600
- RawFullBuckets {
601
- raw : raw,
602
- hashes_end : unsafe { raw. hash . offset ( cap as int ) } ,
603
- table : t,
604
- }
605
- }
606
-
617
+ /// A newtyped RawBucket. Not copyable.
607
618
pub struct RawFullBucket < K , V , M > ( RawBucket < K , V , M > ) ;
608
619
609
620
impl < K , V , M > Deref for RawFullBucket < K , V , M > {
@@ -670,7 +681,7 @@ impl<K, V> Iterator for IntoIter<K, V> {
670
681
self . iter . next ( ) . map ( |bucket| {
671
682
self . iter . table . size -= 1 ;
672
683
unsafe {
673
- let ( k, v) = ptr:: read ( bucket. kval as * const ( K , V ) ) ;
684
+ let ( k, v) = ptr:: read ( bucket. kval ) ;
674
685
( * ( bucket. hash as * mut SafeHash ) , k, v)
675
686
}
676
687
} )
@@ -742,8 +753,8 @@ impl<K, V> Drop for RawTable<K, V> {
742
753
// Avoid double drop of elements that have been already moved out.
743
754
unsafe {
744
755
if self . size != 0 {
745
- for bucket in self . raw_full_buckets_mut ( ) {
746
- ptr:: read ( bucket. kval as * const ( K , V ) ) ;
756
+ for bucket in Bucket :: raw_full_buckets ( self ) {
757
+ ptr:: read ( bucket. kval ) ;
747
758
}
748
759
}
749
760
}
0 commit comments