@@ -85,7 +85,7 @@ pub struct RawTable<K, V> {
8585unsafe impl < K : Send , V : Send > Send for RawTable < K , V > { }
8686unsafe impl < K : Sync , V : Sync > Sync for RawTable < K , V > { }
8787
88- struct RawBucket < K , V > {
88+ pub struct RawBucket < K , V > {
8989 hash : * mut HashUint ,
9090 // We use *const to ensure covariance with respect to K and V
9191 pair : * const ( K , V ) ,
@@ -216,6 +216,10 @@ impl<K, V, M> FullBucket<K, V, M> {
216216 pub fn index ( & self ) -> usize {
217217 self . idx
218218 }
219+ /// Get the raw bucket.
220+ pub fn raw ( & self ) -> RawBucket < K , V > {
221+ self . raw
222+ }
219223}
220224
221225impl < K , V , M > EmptyBucket < K , V , M > {
@@ -230,6 +234,10 @@ impl<K, V, M> Bucket<K, V, M> {
230234 pub fn index ( & self ) -> usize {
231235 self . idx
232236 }
237+ /// get the table.
238+ pub fn into_table ( self ) -> M {
239+ self . table
240+ }
233241}
234242
235243impl < K , V , M > Deref for FullBucket < K , V , M >
@@ -275,6 +283,16 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
275283 Bucket :: at_index ( table, hash. inspect ( ) as usize )
276284 }
277285
286+ pub fn new_from ( r : RawBucket < K , V > , i : usize , t : M )
287+ -> Bucket < K , V , M >
288+ {
289+ Bucket {
290+ raw : r,
291+ idx : i,
292+ table : t,
293+ }
294+ }
295+
278296 pub fn at_index ( table : M , ib_index : usize ) -> Bucket < K , V , M > {
279297 // if capacity is 0, then the RawBucket will be populated with bogus pointers.
280298 // This is an uncommon case though, so avoid it in release builds.
@@ -296,6 +314,40 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
296314 }
297315 }
298316
317+ // "So a few of the first shall be last: for many be called,
318+ // but few chosen."
319+ //
320+ // We'll most likely encounter a few buckets at the beginning that
321+ // have their initial buckets near the end of the table. They were
322+ // placed at the beginning as the probe wrapped around the table
323+ // during insertion. We must skip forward to a bucket that won't
324+ // get reinserted too early and won't unfairly steal others spot.
325+ // This eliminates the need for robin hood.
326+ pub fn head_bucket ( table : M ) -> Bucket < K , V , M > {
327+ let mut bucket = Bucket :: first ( table) ;
328+
329+ loop {
330+ bucket = match bucket. peek ( ) {
331+ Full ( full) => {
332+ if full. displacement ( ) == 0 {
333+ // This bucket occupies its ideal spot.
334+ // It indicates the start of another "cluster".
335+ bucket = full. into_bucket ( ) ;
336+ break ;
337+ }
338+ // Leaving this bucket in the last cluster for later.
339+ full. into_bucket ( )
340+ }
341+ Empty ( b) => {
342+ // Encountered a hole between clusters.
343+ b. into_bucket ( )
344+ }
345+ } ;
346+ bucket. next ( ) ;
347+ }
348+ bucket
349+ }
350+
299351 /// Reads a bucket at a given index, returning an enum indicating whether
300352 /// it's initialized or not. You need to match on this enum to get
301353 /// the appropriate types to call most of the other functions in
@@ -333,6 +385,17 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
333385 self . raw = self . raw . offset ( dist) ;
334386 }
335387 }
388+
389+ /// Modifies the bucket pointer in place to make it point to the previous slot.
390+ pub fn prev ( & mut self ) {
391+ let range = self . table . capacity ( ) ;
392+ let new_idx = self . idx . wrapping_sub ( 1 ) & ( range - 1 ) ;
393+ let dist = ( new_idx as isize ) . wrapping_sub ( self . idx as isize ) ;
394+ self . idx = new_idx;
395+ unsafe {
396+ self . raw = self . raw . offset ( dist) ;
397+ }
398+ }
336399}
337400
338401impl < K , V , M : Deref < Target = RawTable < K , V > > > EmptyBucket < K , V , M > {
@@ -352,7 +415,7 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
352415 }
353416 }
354417
355- pub fn gap_peek ( self ) -> Option < GapThenFull < K , V , M > > {
418+ pub fn gap_peek ( self ) -> Result < GapThenFull < K , V , M > , Bucket < K , V , M > > {
356419 let gap = EmptyBucket {
357420 raw : self . raw ,
358421 idx : self . idx ,
@@ -361,12 +424,12 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
361424
362425 match self . next ( ) . peek ( ) {
363426 Full ( bucket) => {
364- Some ( GapThenFull {
427+ Ok ( GapThenFull {
365428 gap : gap,
366429 full : bucket,
367430 } )
368431 }
369- Empty ( .. ) => None ,
432+ Empty ( e ) => Err ( e . into_bucket ( ) ) ,
370433 }
371434 }
372435}
@@ -529,7 +592,11 @@ impl<K, V, M> GapThenFull<K, V, M>
529592 & self . full
530593 }
531594
532- pub fn shift ( mut self ) -> Option < GapThenFull < K , V , M > > {
595+ pub fn into_bucket ( self ) -> Bucket < K , V , M > {
596+ self . full . into_bucket ( )
597+ }
598+
599+ pub fn shift ( mut self ) -> Result < GapThenFull < K , V , M > , Bucket < K , V , M > > {
533600 unsafe {
534601 * self . gap . raw . hash = mem:: replace ( & mut * self . full . raw . hash , EMPTY_BUCKET ) ;
535602 ptr:: copy_nonoverlapping ( self . full . raw . pair , self . gap . raw . pair as * mut ( K , V ) , 1 ) ;
@@ -544,9 +611,9 @@ impl<K, V, M> GapThenFull<K, V, M>
544611
545612 self . full = bucket;
546613
547- Some ( self )
614+ Ok ( self )
548615 }
549- Empty ( .. ) => None ,
616+ Empty ( b ) => Err ( b . into_bucket ( ) ) ,
550617 }
551618 }
552619}
0 commit comments