@@ -45,8 +45,11 @@ type hashmapIterator struct {
45
45
buckets unsafe.Pointer // pointer to array of hashapBuckets
46
46
numBuckets uintptr // length of buckets array
47
47
bucketNumber uintptr // current index into buckets array
48
+ startBucket uintptr // starting location for iterator
48
49
bucket * hashmapBucket // current bucket in chain
49
50
bucketIndex uint8 // current index into bucket
51
+ startIndex uint8 // starting bucket index for iterator
52
+ wrapped bool // true if the iterator has wrapped
50
53
}
51
54
52
55
func hashmapNewIterator () unsafe.Pointer {
@@ -390,28 +393,44 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo
390
393
// initialize iterator
391
394
it .buckets = m .buckets
392
395
it .numBuckets = uintptr (1 ) << m .bucketBits
396
+ it .startBucket = uintptr (fastrand ()) & (it .numBuckets - 1 )
397
+ it .startIndex = uint8 (fastrand () & 7 )
398
+
399
+ it .bucketNumber = it .startBucket
400
+ it .bucket = hashmapBucketAddr (m , it .buckets , it .bucketNumber )
401
+ it .bucketIndex = it .startIndex
393
402
}
394
403
395
404
for {
405
+ // If we've wrapped and we're back at our starting location, terminate the iteration.
406
+ if it .wrapped && it .bucketNumber == it .startBucket && it .bucketIndex == it .startIndex {
407
+ return false
408
+ }
409
+
396
410
if it .bucketIndex >= 8 {
397
411
// end of bucket, move to the next in the chain
398
412
it .bucketIndex = 0
399
413
it .bucket = it .bucket .next
400
414
}
415
+
401
416
if it .bucket == nil {
417
+ it .bucketNumber ++ // next bucket
402
418
if it .bucketNumber >= it .numBuckets {
403
- // went through all buckets
404
- return false
419
+ // went through all buckets -- wrap around
420
+ it .bucketNumber = 0
421
+ it .wrapped = true
405
422
}
406
423
it .bucket = hashmapBucketAddr (m , it .buckets , it .bucketNumber )
407
- it . bucketNumber ++ // next bucket
424
+ continue
408
425
}
426
+
409
427
if it .bucket .tophash [it .bucketIndex ] == 0 {
410
428
// slot is empty - move on
411
429
it .bucketIndex ++
412
430
continue
413
431
}
414
432
433
+ // Found a key.
415
434
slotKey := hashmapSlotKey (m , it .bucket , it .bucketIndex )
416
435
memcpy (key , slotKey , m .keySize )
417
436
0 commit comments