@@ -24,7 +24,7 @@ use ops::{Deref, DerefMut, Drop};
2424use option:: Option :: { self , Some , None } ;
2525use ptr:: { self , Unique , PtrExt } ;
2626use result:: Result :: { self , Ok , Err } ;
27- use rt:: heap:: { allocate, deallocate, EMPTY } ;
27+ use rt:: heap:: { EMPTY , allocate, deallocate, reallocate_inplace } ;
2828use collections:: hash_state:: HashState ;
2929use core:: nonzero:: NonZero ;
3030
@@ -180,15 +180,15 @@ impl<K, V, M, S> Borrow<RawTable<K, V>> for Bucket<K, V, M, S>
180180 where M : Borrow < RawTable < K , V > >
181181{
182182 fn borrow ( & self ) -> & RawTable < K , V > {
183- bucket . table . 0 . borrow ( )
183+ self . table . 0 . borrow ( )
184184 }
185185}
186186
187187impl < K , V , M , S > BorrowMut < RawTable < K , V > > for Bucket < K , V , M , S >
188188 where M : Borrow < RawTable < K , V > >
189189{
190190 fn borrow_mut ( & mut self ) -> & mut RawTable < K , V > {
191- bucket . table . 0 . borrow_mut ( )
191+ self . table . 0 . borrow_mut ( )
192192 }
193193}
194194
@@ -252,6 +252,14 @@ impl<K, V, M> Bucket<K, V, M> where M: Borrow<RawTable<K, V>> {
252252 Bucket :: at_index ( table, 0 ) . map ( |b| b. into_iter ( ) ) . unwrap_or_else ( |b| b. into_iter ( ) )
253253 }
254254
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+
255263 /// Reads a bucket at a given index, returning an enum indicating whether
256264 /// it's initialized or not. You need to match on this enum to get
257265 /// the appropriate types to call most of the other functions in
@@ -460,7 +468,7 @@ impl<K, V> RawTable<K, V> {
460468 RawTable {
461469 capacity : capacity,
462470 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 ) ) ,
464472 }
465473 } ;
466474
@@ -495,6 +503,47 @@ impl<K, V> RawTable<K, V> {
495503 }
496504 }
497505
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+
498547 /// The hashtable's capacity, similar to a vector's.
499548 pub fn capacity ( & self ) -> usize {
500549 self . capacity
@@ -551,13 +600,13 @@ fn align<K, V>() -> usize {
551600/// A newtyped RawBucket. Not copyable.
552601pub struct RawFullBucket < K , V , M > ( RawBucket < K , V > ) ;
553602
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 > > {
555604 pub fn into_refs ( self ) -> ( & ' t K , & ' t V ) {
556605 unsafe { ( & ( * self . 0 . kval ) . 0 , & ( * self . 0 . kval ) . 1 ) }
557606 }
558607}
559608
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 > > {
561610 pub fn into_mut_refs ( self ) -> ( & ' t mut K , & ' t mut V ) {
562611 unsafe { ( & mut ( * self . 0 . kval ) . 0 , & mut ( * self . 0 . kval ) . 1 ) }
563612 }
0 commit comments