mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-21 21:09:02 +00:00
+22
-3
@@ -45,8 +45,11 @@ type hashmapIterator struct {
|
|||||||
buckets unsafe.Pointer // pointer to array of hashapBuckets
|
buckets unsafe.Pointer // pointer to array of hashapBuckets
|
||||||
numBuckets uintptr // length of buckets array
|
numBuckets uintptr // length of buckets array
|
||||||
bucketNumber uintptr // current index into buckets array
|
bucketNumber uintptr // current index into buckets array
|
||||||
|
startBucket uintptr // starting location for iterator
|
||||||
bucket *hashmapBucket // current bucket in chain
|
bucket *hashmapBucket // current bucket in chain
|
||||||
bucketIndex uint8 // current index into bucket
|
bucketIndex uint8 // current index into bucket
|
||||||
|
startIndex uint8 // starting bucket index for iterator
|
||||||
|
wrapped bool // true if the iterator has wrapped
|
||||||
}
|
}
|
||||||
|
|
||||||
func hashmapNewIterator() unsafe.Pointer {
|
func hashmapNewIterator() unsafe.Pointer {
|
||||||
@@ -390,28 +393,44 @@ func hashmapNext(m *hashmap, it *hashmapIterator, key, value unsafe.Pointer) boo
|
|||||||
// initialize iterator
|
// initialize iterator
|
||||||
it.buckets = m.buckets
|
it.buckets = m.buckets
|
||||||
it.numBuckets = uintptr(1) << m.bucketBits
|
it.numBuckets = uintptr(1) << m.bucketBits
|
||||||
|
it.startBucket = uintptr(fastrand()) & (it.numBuckets - 1)
|
||||||
|
it.startIndex = uint8(fastrand() & 7)
|
||||||
|
|
||||||
|
it.bucketNumber = it.startBucket
|
||||||
|
it.bucket = hashmapBucketAddr(m, it.buckets, it.bucketNumber)
|
||||||
|
it.bucketIndex = it.startIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// If we've wrapped and we're back at our starting location, terminate the iteration.
|
||||||
|
if it.wrapped && it.bucketNumber == it.startBucket && it.bucketIndex == it.startIndex {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if it.bucketIndex >= 8 {
|
if it.bucketIndex >= 8 {
|
||||||
// end of bucket, move to the next in the chain
|
// end of bucket, move to the next in the chain
|
||||||
it.bucketIndex = 0
|
it.bucketIndex = 0
|
||||||
it.bucket = it.bucket.next
|
it.bucket = it.bucket.next
|
||||||
}
|
}
|
||||||
|
|
||||||
if it.bucket == nil {
|
if it.bucket == nil {
|
||||||
|
it.bucketNumber++ // next bucket
|
||||||
if it.bucketNumber >= it.numBuckets {
|
if it.bucketNumber >= it.numBuckets {
|
||||||
// went through all buckets
|
// went through all buckets -- wrap around
|
||||||
return false
|
it.bucketNumber = 0
|
||||||
|
it.wrapped = true
|
||||||
}
|
}
|
||||||
it.bucket = hashmapBucketAddr(m, it.buckets, it.bucketNumber)
|
it.bucket = hashmapBucketAddr(m, it.buckets, it.bucketNumber)
|
||||||
it.bucketNumber++ // next bucket
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if it.bucket.tophash[it.bucketIndex] == 0 {
|
if it.bucket.tophash[it.bucketIndex] == 0 {
|
||||||
// slot is empty - move on
|
// slot is empty - move on
|
||||||
it.bucketIndex++
|
it.bucketIndex++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Found a key.
|
||||||
slotKey := hashmapSlotKey(m, it.bucket, it.bucketIndex)
|
slotKey := hashmapSlotKey(m, it.bucket, it.bucketIndex)
|
||||||
memcpy(key, slotKey, m.keySize)
|
memcpy(key, slotKey, m.keySize)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user