@@ -24,7 +24,7 @@ use ops::{Deref, DerefMut, Drop};
24
24
use option:: Option :: { self , Some , None } ;
25
25
use ptr:: { self , Unique , PtrExt } ;
26
26
use result:: Result :: { self , Ok , Err } ;
27
- use rt:: heap:: { allocate, deallocate, EMPTY } ;
27
+ use rt:: heap:: { EMPTY , allocate, deallocate, reallocate_inplace } ;
28
28
use collections:: hash_state:: HashState ;
29
29
use core:: nonzero:: NonZero ;
30
30
@@ -180,15 +180,15 @@ impl<K, V, M, S> Borrow<RawTable<K, V>> for Bucket<K, V, M, S>
180
180
where M : Borrow < RawTable < K , V > >
181
181
{
182
182
fn borrow ( & self ) -> & RawTable < K , V > {
183
- bucket . table . 0 . borrow ( )
183
+ self . table . 0 . borrow ( )
184
184
}
185
185
}
186
186
187
187
impl < K , V , M , S > BorrowMut < RawTable < K , V > > for Bucket < K , V , M , S >
188
188
where M : Borrow < RawTable < K , V > >
189
189
{
190
190
fn borrow_mut ( & mut self ) -> & mut RawTable < K , V > {
191
- bucket . table . 0 . borrow_mut ( )
191
+ self . table . 0 . borrow_mut ( )
192
192
}
193
193
}
194
194
@@ -252,6 +252,14 @@ impl<K, V, M> Bucket<K, V, M> where M: Borrow<RawTable<K, V>> {
252
252
Bucket :: at_index ( table, 0 ) . map ( |b| b. into_iter ( ) ) . unwrap_or_else ( |b| b. into_iter ( ) )
253
253
}
254
254
255
+ /// Narrows down the range of iteration, which must be a power of 2.
256
+ pub fn iter_to ( mut self , limit : usize ) -> Bucket < K , V , M > {
257
+ assert ! ( limit <= self . table. capacity( ) ) ;
258
+ assert ! ( limit. is_power_of_two( ) ) ;
259
+ self . capacity = limit;
260
+ self
261
+ }
262
+
255
263
/// Reads a bucket at a given index, returning an enum indicating whether
256
264
/// it's initialized or not. You need to match on this enum to get
257
265
/// the appropriate types to call most of the other functions in
@@ -460,7 +468,7 @@ impl<K, V> RawTable<K, V> {
460
468
RawTable {
461
469
capacity : capacity,
462
470
size : 0 ,
463
- middle : Unique ( ( hashes as * mut ( K , V ) ) . offset ( capacity as isize ) ) ,
471
+ middle : Unique :: new ( ( hashes as * mut ( K , V ) ) . offset ( capacity as isize ) ) ,
464
472
}
465
473
} ;
466
474
@@ -495,6 +503,47 @@ impl<K, V> RawTable<K, V> {
495
503
}
496
504
}
497
505
506
+ pub fn grow_inplace ( & mut self , capacity : uint ) -> bool {
507
+ assert ! ( capacity. is_power_of_two( ) ) ;
508
+ assert ! ( capacity >= self . capacity) ;
509
+
510
+ if self . middle . ptr . is_null ( ) {
511
+ return false ;
512
+ }
513
+
514
+ let new_size = checked_size_generic :: < K , V > ( capacity) ;
515
+
516
+ unsafe {
517
+ let ptr = self . middle . ptr . offset ( -( self . capacity as isize ) ) as * mut u8 ;
518
+ let is_inplace = reallocate_inplace ( ptr,
519
+ size_generic :: < K , V > ( self . capacity ) ,
520
+ new_size,
521
+ align :: < K , V > ( ) ) >= new_size;
522
+
523
+ if is_inplace {
524
+ let cap_diff = ( capacity - self . capacity ) as isize ;
525
+ let hashes = self . middle . ptr . offset ( cap_diff) as * mut Option < SafeHash > ;
526
+ // Copy the array of hashes. Maybe it's already in cache.
527
+ if size_of :: < ( K , V ) > ( ) >= size_of :: < Option < SafeHash > > ( ) {
528
+ // The regions of memory occupied by old and new hash arrays are disjoint.
529
+ // before: [KVKVKVKV|h h h h ]
530
+ // after: [KVKVKVKV|KVKVKVKV|h h h h h h h h ]
531
+ ptr:: copy_nonoverlapping ( hashes, self . middle . ptr as * const _ , self . capacity ) ;
532
+ } else {
533
+ // before: [KVKVKVKV|h h |h h ]
534
+ // after: [KVKVKVKV|KVKVKVKV|h h h h h h h h ]
535
+ ptr:: copy ( hashes, self . middle . ptr as * const _ , self . capacity ) ;
536
+ }
537
+ zero_memory ( hashes. offset ( self . capacity as int ) , capacity - self . capacity ) ;
538
+
539
+ self . middle = Unique :: new ( self . middle . ptr . offset ( cap_diff) ) ;
540
+ self . capacity = capacity;
541
+ }
542
+
543
+ return is_inplace;
544
+ }
545
+ }
546
+
498
547
/// The hashtable's capacity, similar to a vector's.
499
548
pub fn capacity ( & self ) -> usize {
500
549
self . capacity
@@ -551,13 +600,13 @@ fn align<K, V>() -> usize {
551
600
/// A newtyped RawBucket. Not copyable.
552
601
pub struct RawFullBucket < K , V , M > ( RawBucket < K , V > ) ;
553
602
554
- impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where RawTable < K , V > : BorrowFrom < M > {
603
+ impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where M : Borrow < RawTable < K , V > > {
555
604
pub fn into_refs ( self ) -> ( & ' t K , & ' t V ) {
556
605
unsafe { ( & ( * self . 0 . kval ) . 0 , & ( * self . 0 . kval ) . 1 ) }
557
606
}
558
607
}
559
608
560
- impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where RawTable < K , V > : BorrowFromMut < M > {
609
+ impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where M : BorrowMut < RawTable < K , V > > {
561
610
pub fn into_mut_refs ( self ) -> ( & ' t mut K , & ' t mut V ) {
562
611
unsafe { ( & mut ( * self . 0 . kval ) . 0 , & mut ( * self . 0 . kval ) . 1 ) }
563
612
}
0 commit comments