@@ -22,9 +22,9 @@ use mem::{self, min_align_of, size_of};
2222use num:: { Int , UnsignedInt } ;
2323use ops:: { Deref , DerefMut , Drop } ;
2424use option:: Option :: { self , Some , None } ;
25- use ptr:: { self , Unique , PtrExt , copy_nonoverlapping_memory, zero_memory} ;
25+ use ptr:: { self , Unique , PtrExt , copy_memory , copy_nonoverlapping_memory, zero_memory} ;
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
@@ -199,15 +199,15 @@ impl<K, V, M, S> Borrow<RawTable<K, V>> for Bucket<K, V, M, S>
199199 where M : Borrow < RawTable < K , V > >
200200{
201201 fn borrow ( & self ) -> & RawTable < K , V > {
202- bucket . table . 0 . borrow ( )
202+ self . table . 0 . borrow ( )
203203 }
204204}
205205
206206impl < K , V , M , S > BorrowMut < RawTable < K , V > > for Bucket < K , V , M , S >
207207 where M : Borrow < RawTable < K , V > >
208208{
209209 fn borrow_mut ( & mut self ) -> & mut RawTable < K , V > {
210- bucket . table . 0 . borrow_mut ( )
210+ self . table . 0 . borrow_mut ( )
211211 }
212212}
213213
@@ -271,6 +271,14 @@ impl<K, V, M> Bucket<K, V, M> where M: Borrow<RawTable<K, V>> {
271271 Bucket :: at_index ( table, 0 ) . map ( |b| b. into_iter ( ) ) . unwrap_or_else ( |b| b. into_iter ( ) )
272272 }
273273
274+ /// Narrows down the range of iteration, which must be a power of 2.
275+ pub fn iter_to ( mut self , limit : usize ) -> Bucket < K , V , M > {
276+ assert ! ( limit <= self . table. capacity( ) ) ;
277+ assert ! ( limit. is_power_of_two( ) ) ;
278+ self . capacity = limit;
279+ self
280+ }
281+
274282 /// Reads a bucket at a given index, returning an enum indicating whether
275283 /// it's initialized or not. You need to match on this enum to get
276284 /// the appropriate types to call most of the other functions in
@@ -479,7 +487,7 @@ impl<K, V> RawTable<K, V> {
479487 RawTable {
480488 capacity : capacity,
481489 size : 0 ,
482- middle : Unique ( ( hashes as * mut ( K , V ) ) . offset ( capacity as isize ) ) ,
490+ middle : Unique :: new ( ( hashes as * mut ( K , V ) ) . offset ( capacity as isize ) ) ,
483491 }
484492 } ;
485493
@@ -514,6 +522,47 @@ impl<K, V> RawTable<K, V> {
514522 }
515523 }
516524
525+ pub fn grow_inplace ( & mut self , capacity : uint ) -> bool {
526+ assert ! ( capacity. is_power_of_two( ) ) ;
527+ assert ! ( capacity >= self . capacity) ;
528+
529+ if self . middle . ptr . is_null ( ) {
530+ return false ;
531+ }
532+
533+ let new_size = checked_size_generic :: < K , V > ( capacity) ;
534+
535+ unsafe {
536+ let ptr = self . middle . ptr . offset ( -( self . capacity as isize ) ) as * mut u8 ;
537+ let is_inplace = reallocate_inplace ( ptr,
538+ size_generic :: < K , V > ( self . capacity ) ,
539+ new_size,
540+ align :: < K , V > ( ) ) >= new_size;
541+
542+ if is_inplace {
543+ let cap_diff = ( capacity - self . capacity ) as isize ;
544+ let hashes = self . middle . ptr . offset ( cap_diff) as * mut Option < SafeHash > ;
545+ // Copy the array of hashes. Maybe it's already in cache.
546+ if size_of :: < ( K , V ) > ( ) >= size_of :: < Option < SafeHash > > ( ) {
547+ // The regions of memory occupied by old and new hash arrays are disjoint.
548+ // before: [KVKVKVKV|h h h h ]
549+ // after: [KVKVKVKV|KVKVKVKV|h h h h h h h h ]
550+ copy_nonoverlapping_memory ( hashes, self . middle . ptr as * const _ , self . capacity ) ;
551+ } else {
552+ // before: [KVKVKVKV|h h |h h ]
553+ // after: [KVKVKVKV|KVKVKVKV|h h h h h h h h ]
554+ copy_memory ( hashes, self . middle . ptr as * const _ , self . capacity ) ;
555+ }
556+ zero_memory ( hashes. offset ( self . capacity as int ) , capacity - self . capacity ) ;
557+
558+ self . middle = Unique :: new ( self . middle . ptr . offset ( cap_diff) ) ;
559+ self . capacity = capacity;
560+ }
561+
562+ return is_inplace;
563+ }
564+ }
565+
517566 /// The hashtable's capacity, similar to a vector's.
518567 pub fn capacity ( & self ) -> usize {
519568 self . capacity
@@ -570,13 +619,13 @@ fn align<K, V>() -> usize {
570619/// A newtyped RawBucket. Not copyable.
571620pub struct RawFullBucket < K , V , M > ( RawBucket < K , V > ) ;
572621
573- impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where RawTable < K , V > : BorrowFrom < M > {
622+ impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where M : Borrow < RawTable < K , V > > {
574623 pub fn into_refs ( self ) -> ( & ' t K , & ' t V ) {
575624 unsafe { ( & ( * self . 0 . kval ) . 0 , & ( * self . 0 . kval ) . 1 ) }
576625 }
577626}
578627
579- impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where RawTable < K , V > : BorrowFromMut < M > {
628+ impl < ' t , K , V , M : ' t > RawFullBucket < K , V , M > where M : BorrowMut < RawTable < K , V > > {
580629 pub fn into_mut_refs ( self ) -> ( & ' t mut K , & ' t mut V ) {
581630 unsafe { ( & mut ( * self . 0 . kval ) . 0 , & mut ( * self . 0 . kval ) . 1 ) }
582631 }
0 commit comments