cockroachdb / cockroachdb/swiss
Mutating the map while iterating All() is unhealthy
- Dominant language
- Go
- Stars
- 477
- Forks
- 21
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 1
Description
There's two ways in which the following test case fails. It either fails because the same key is seen twice or `require.EqualValues(t, e, vals)` fails because some of the expected keys were not seen at all. So run it multiple times to see both behaviours. The bug is somehow caused by the fact that during splitting the original bucket instance is reused but I forgot my thought process on how I arrived there.
```golang
func TestIterateMutate2(t *testing.T) {
for repeat := 0; repeat < 10*1000; repeat++ {
m := New[int, int](0)
// initialize map so that it will split during the Put()s done during All()
for i := 0; i < int(defaultMaxBucketCapacity*groupSize*3/4); i++ {
m.Put(i, i)
}
e := m.toBuiltinMap()
require.EqualValues(t, (defaultMaxBucketCapacity * groupSize * 3 / 4), m.Len())
require.EqualValues(t, (defaultMaxBucketCapacity * groupSize * 3 / 4), len(e))
// Iterate over the map, occasionally inserting new entries to it.
vals := make(map[int]int)
fools := make(map[int]int)
fool := m.Len() + 10
foolstart := fool
m.All(func(k, v int) bool {
if (k % 10) == 0 {
m.Put(fool, fool)
fool++
}
if k >= foolstart {
// Did we see this key already?
if v2, ok := fools[k]; ok {
t.Fatalf("visiting key %v for the second time! Previously we got value %v, now %v", k, v2, v)
}
fools[k] = v
return true
}
// Did we see this key already?
if v2, ok := vals[k]; ok {
t.Fatalf("visiting key %v for the second time! Previously we got value %v, now %v", k, v2, v)
}
vals[k] = v
return true
})
require.EqualValues(t, e, vals)
}
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.