mirror of
https://github.com/golang/go
synced 2024-10-02 04:18:33 -06:00
runtime: calculate k only once in mapiternext
Make the calculation of k and v a bit lazier. None of the following code cares about indirect-vs-direct k, and it happens on all code paths, so check t.indirectkey earlier. Simplifies the code and reduces both machine code and stack size. Change-Id: I5ea4c0772848d7a4b15383baedb9a1f7feb47201 Reviewed-on: https://go-review.googlesource.com/55092 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
29e9b89b9a
commit
589fc314af
@ -820,11 +820,14 @@ next:
|
||||
}
|
||||
for ; i < bucketCnt; i++ {
|
||||
offi := (i + it.offset) & (bucketCnt - 1)
|
||||
k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
|
||||
v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize))
|
||||
if b.tophash[offi] == empty || b.tophash[offi] == evacuatedEmpty {
|
||||
continue
|
||||
}
|
||||
k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
|
||||
if t.indirectkey {
|
||||
k = *((*unsafe.Pointer)(k))
|
||||
}
|
||||
v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize))
|
||||
if checkBucket != noCheck && !h.sameSizeGrow() {
|
||||
// Special case: iterator was started during a grow to a larger size
|
||||
// and the grow is not done yet. We're working on a bucket whose
|
||||
@ -833,14 +836,10 @@ next:
|
||||
// through the oldbucket, skipping any keys that will go
|
||||
// to the other new bucket (each oldbucket expands to two
|
||||
// buckets during a grow).
|
||||
k2 := k
|
||||
if t.indirectkey {
|
||||
k2 = *((*unsafe.Pointer)(k2))
|
||||
}
|
||||
if t.reflexivekey || alg.equal(k2, k2) {
|
||||
if t.reflexivekey || alg.equal(k, k) {
|
||||
// If the item in the oldbucket is not destined for
|
||||
// the current new bucket in the iteration, skip it.
|
||||
hash := alg.hash(k2, uintptr(h.hash0))
|
||||
hash := alg.hash(k, uintptr(h.hash0))
|
||||
if hash&(uintptr(1)<<it.B-1) != checkBucket {
|
||||
continue
|
||||
}
|
||||
@ -859,9 +858,6 @@ next:
|
||||
}
|
||||
if b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY {
|
||||
// this is the golden data, we can return it.
|
||||
if t.indirectkey {
|
||||
k = *((*unsafe.Pointer)(k))
|
||||
}
|
||||
it.key = k
|
||||
if t.indirectvalue {
|
||||
v = *((*unsafe.Pointer)(v))
|
||||
@ -870,17 +866,13 @@ next:
|
||||
} else {
|
||||
// The hash table has grown since the iterator was started.
|
||||
// The golden data for this key is now somewhere else.
|
||||
k2 := k
|
||||
if t.indirectkey {
|
||||
k2 = *((*unsafe.Pointer)(k2))
|
||||
}
|
||||
if t.reflexivekey || alg.equal(k2, k2) {
|
||||
if t.reflexivekey || alg.equal(k, k) {
|
||||
// Check the current hash table for the data.
|
||||
// This code handles the case where the key
|
||||
// has been deleted, updated, or deleted and reinserted.
|
||||
// NOTE: we need to regrab the key as it has potentially been
|
||||
// updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
|
||||
rk, rv := mapaccessK(t, h, k2)
|
||||
rk, rv := mapaccessK(t, h, k)
|
||||
if rk == nil {
|
||||
continue // key has been deleted
|
||||
}
|
||||
@ -891,7 +883,7 @@ next:
|
||||
// updated, so we can just return it. That's lucky for
|
||||
// us because when key!=key we can't look it up
|
||||
// successfully in the current table.
|
||||
it.key = k2
|
||||
it.key = k
|
||||
if t.indirectvalue {
|
||||
v = *((*unsafe.Pointer)(v))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user