关于 sync.Map.Range 源码
来源:13-3 实现SyncDict(二)

弦歌ty
2022-06-21
老师,请问一下,Range 源码中的 read.amended 是什么意思,是用来确定 map 是否可以用吗?这个注释没太看懂,以及为什么要两次确认 read.amended?
func (m *Map) Range(f func(key, value any) bool) {
// We need to be able to iterate over all of the keys that were already
// present at the start of the call to Range.
// If read.amended is false, then read.m satisfies that property without
// requiring us to hold m.mu for a long time.
read, _ := m.read.Load().(readOnly)
if read.amended {
// m.dirty contains keys not in read.m. Fortunately, Range is already O(N)
// (assuming the caller does not break out early), so a call to Range
// amortizes an entire copy of the map: we can promote the dirty copy
// immediately!
m.mu.Lock()
read, _ = m.read.Load().(readOnly)
if read.amended {
read = readOnly{m: m.dirty}
m.read.Store(read)
m.dirty = nil
m.misses = 0
}
m.mu.Unlock()
}
for k, e := range read.m {
v, ok := e.load()
if !ok {
continue
}
if !f(k, v) {
break
}
}
}
写回答
1回答
-
Moody
2022-06-21
amended这个在4-7和4-8应该是提到过,指的是read有没有被追加,如果是true的话,代表read里面并不是完整的数据,dirty里面有新数据。
这个地方确认两次,是为了防止m.mu.Lock()等待加锁时,dirty做了提升,这样dirty就空了,amended也变为false了。
00
相似问题