@@ -85,7 +85,7 @@ pub struct RawTable<K, V> {
85
85
unsafe impl < K : Send , V : Send > Send for RawTable < K , V > { }
86
86
unsafe impl < K : Sync , V : Sync > Sync for RawTable < K , V > { }
87
87
88
- struct RawBucket < K , V > {
88
+ pub struct RawBucket < K , V > {
89
89
hash : * mut HashUint ,
90
90
// We use *const to ensure covariance with respect to K and V
91
91
pair : * const ( K , V ) ,
@@ -216,6 +216,10 @@ impl<K, V, M> FullBucket<K, V, M> {
216
216
pub fn index ( & self ) -> usize {
217
217
self . idx
218
218
}
219
+ /// Get the raw bucket.
220
+ pub fn raw ( & self ) -> RawBucket < K , V > {
221
+ self . raw
222
+ }
219
223
}
220
224
221
225
impl < K , V , M > EmptyBucket < K , V , M > {
@@ -230,6 +234,10 @@ impl<K, V, M> Bucket<K, V, M> {
230
234
pub fn index ( & self ) -> usize {
231
235
self . idx
232
236
}
237
+ /// get the table.
238
+ pub fn into_table ( self ) -> M {
239
+ self . table
240
+ }
233
241
}
234
242
235
243
impl < 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> {
275
283
Bucket :: at_index ( table, hash. inspect ( ) as usize )
276
284
}
277
285
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
+
278
296
pub fn at_index ( table : M , ib_index : usize ) -> Bucket < K , V , M > {
279
297
// if capacity is 0, then the RawBucket will be populated with bogus pointers.
280
298
// 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> {
296
314
}
297
315
}
298
316
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
+
299
351
/// Reads a bucket at a given index, returning an enum indicating whether
300
352
/// it's initialized or not. You need to match on this enum to get
301
353
/// 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> {
333
385
self . raw = self . raw . offset ( dist) ;
334
386
}
335
387
}
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
+ }
336
399
}
337
400
338
401
impl < 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> {
352
415
}
353
416
}
354
417
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 > > {
356
419
let gap = EmptyBucket {
357
420
raw : self . raw ,
358
421
idx : self . idx ,
@@ -361,12 +424,12 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
361
424
362
425
match self . next ( ) . peek ( ) {
363
426
Full ( bucket) => {
364
- Some ( GapThenFull {
427
+ Ok ( GapThenFull {
365
428
gap : gap,
366
429
full : bucket,
367
430
} )
368
431
}
369
- Empty ( .. ) => None ,
432
+ Empty ( e ) => Err ( e . into_bucket ( ) ) ,
370
433
}
371
434
}
372
435
}
@@ -529,7 +592,11 @@ impl<K, V, M> GapThenFull<K, V, M>
529
592
& self . full
530
593
}
531
594
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 > > {
533
600
unsafe {
534
601
* self . gap . raw . hash = mem:: replace ( & mut * self . full . raw . hash , EMPTY_BUCKET ) ;
535
602
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>
544
611
545
612
self . full = bucket;
546
613
547
- Some ( self )
614
+ Ok ( self )
548
615
}
549
- Empty ( .. ) => None ,
616
+ Empty ( b ) => Err ( b . into_bucket ( ) ) ,
550
617
}
551
618
}
552
619
}
0 commit comments