-
Notifications
You must be signed in to change notification settings - Fork 118
Open
Labels
Description
Describe the bug
When multiple coroutines call GetOrInsert
at the same time, data may be missed during Range query.
To Reproduce
func main() {
m := hashmap.New[string, bool]()
wg := sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
kk := strconv.Itoa(i)
go func() {
m.GetOrInsert(kk, true)
wg.Done()
}()
}
wg.Wait()
tmp := make([]string, 0)
m.Range(func(key string, value bool) bool {
tmp = append(tmp, key)
return true
})
log.Println(len(tmp), "/", m.Len()) // print: 9XX / 1000
}
Expected behavior
Return data correctly
System (please complete the following information):
- OS: macos / linux
- Version / Commit: 1.0.8
Additional context
When called repeatedly, Len()
may be larger than the actual length.
func main() {
m := hashmap.New[string, bool]()
wg := sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
kk := strconv.Itoa(i)
go func() {
m.GetOrInsert(kk, true) // call
m.GetOrInsert(kk, true) // repeat call
m.GetOrInsert(kk, true) // repeat call
m.GetOrInsert(kk, true) // repeat call
wg.Done()
}()
}
wg.Wait()
tmp := make([]string, 0)
m.Range(func(key string, value bool) bool {
tmp = append(tmp, key)
return true
})
log.Println(m.Len()) // m.Len() may be > 1000
}