Question about iterator implementation of golang map

109 views
Skip to first unread message

Aaron Lau

unread,
Jul 15, 2019, 10:40:04 AM7/15/19
to golang-nuts
Question:
Where
In function mapiternext
Why
We won't update the map during the traversal process. So why use mapaccessK to find the k & v again ?

if (b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY) ||
!(t.reflexivekey() || alg.equal(k, k)) {
// This is the golden data, we can return it.
// OR
// key!=key, so the entry can't be deleted or updated, so we can just return it.
// That's lucky for us because when key!=key we can't look it up successfully.
it.key = k
if t.indirectvalue() {
v = *((*unsafe.Pointer)(v))
}
it.value = v
} else {
// The hash table has grown since the iterator was started.
// The golden data for this key is now somewhere else.
// 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, k)
if rk == nil {
continue // key has been deleted
}
it.key = rk
it.value = rv
}

Jan Mercl

unread,
Jul 15, 2019, 10:57:48 AM7/15/19
to Aaron Lau, golang-nuts
On Mon, Jul 15, 2019 at 4:39 PM Aaron Lau <lslj...@gmail.com> wrote:

> We won't update the map during the traversal process. So why use mapaccessK to find the k & v again ?

The comment explains that very clearly:

> // The hash table has grown since the iterator was started.
> // The golden data for this key is now somewhere else.
> // 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, k)

Iteration does nut mutate the map, correct. But the code that iterates
the map may mutate it.

for k, v := range m {
if cond(k, v) {
m[2*k] = 3*v
}
}
Reply all
Reply to author
Forward
0 new messages