Skip to content

Instantly share code, notes, and snippets.

@bnm3k
Last active July 21, 2020 14:16
Show Gist options
  • Save bnm3k/53a16151b17215ff0c5dae37636f5d56 to your computer and use it in GitHub Desktop.
Save bnm3k/53a16151b17215ff0c5dae37636f5d56 to your computer and use it in GitHub Desktop.
Single writer, multiple readers google/btree data race
package main
import (
"math/rand"
"sync"
"time"
"github.com/google/btree"
)
// perm returns a random permutation of n Int items in the range [0, n).
// credits for this fn: github.com/google/btree/btree_test.go
func perm(n int) (out []btree.Item) {
for _, v := range rand.Perm(n) {
out = append(out, btree.Int(v))
}
return
}
func btreeReader(tr *btree.BTree, quitCh chan struct{}, wg *sync.WaitGroup) {
n := 10
items := perm(n)
for {
select {
case <-quitCh:
wg.Done()
return
default:
i := rand.Intn(n)
tr.Get(items[i])
}
}
}
func btreeWriter(tr *btree.BTree, quitCh chan struct{}, wg *sync.WaitGroup) {
n := 10
items := perm(n)
for {
select {
case <-quitCh:
wg.Done()
return
default:
i := rand.Intn(n)
if i%2 == 0 {
tr.ReplaceOrInsert(items[i])
} else {
tr.Delete(items[i])
}
}
}
}
func main() {
numReaders := 10
quitCh := make(chan struct{}, numReaders+1)
var wg sync.WaitGroup
wg.Add(numReaders + 1)
// btree
tr := btree.New(20)
// start readers
for i := 0; i < numReaders; i++ {
go btreeReader(tr, quitCh, &wg)
}
// start single writer
go btreeWriter(tr, quitCh, &wg)
time.Sleep(3 * time.Second)
for i := 0; i < numReaders+1; i++ {
quitCh <- struct{}{}
}
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment