lotusdb
lotusdb copied to clipboard
the Arena function growBufSize() may have concurrency issue
https://github.com/flower-corp/lotusdb/blob/0f5d9df69c7fdcd1e8e3054e2a63f3a36441feca/arenaskl/arena.go#L125-L129
When different goroutines run to the growBufSize(), newBuf allocated by one goroutine may replaced by another. Replacement of buf and newBuf is not atomic. I just modified the skl_test.go and found this error and I don't know if it is designed that way
// TestConcurrentBasic tests concurrent writes followed by concurrent reads.
func TestConcurrentBasic(t *testing.T) {
const n = 1000
// Set testing flag to make it easier to trigger unusual race conditions.
//l := NewSkiplist(NewArena(arenaSize))
// Change NewArena size to a small one
l := NewSkiplist(NewArena(10))
l.testing = true
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
var it Iterator
it.Init(l)
it.Put([]byte(fmt.Sprintf("%05d", i)), newValue(i))
}(i)
}
wg.Wait()
// Check values. Concurrent reads.
for i := 0; i < n; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
var it Iterator
it.Init(l)
found := it.Seek([]byte(fmt.Sprintf("%05d", i)))
require.True(t, found)
require.EqualValues(t, newValue(i), it.Value())
}(i)
}
wg.Wait()
require.Equal(t, n, length(l))
require.Equal(t, n, lengthRev(l))
}
ok, I will check it.