mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/mergeset: use deterministic random generator in tests
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3683
This commit is contained in:
parent
7030429958
commit
1a3a6ef907
7 changed files with 64 additions and 51 deletions
|
@ -2,16 +2,18 @@ package mergeset
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBlockStreamReaderReadFromInmemoryPart(t *testing.T) {
|
func TestBlockStreamReaderReadFromInmemoryPart(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
var items []string
|
var items []string
|
||||||
var ib inmemoryBlock
|
var ib inmemoryBlock
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
item := getRandomBytes()
|
item := getRandomBytes(r)
|
||||||
if !ib.Add(item) {
|
if !ib.Add(item) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
"testing/quick"
|
"testing/quick"
|
||||||
|
|
||||||
|
@ -33,6 +32,8 @@ func TestCommonPrefixLen(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInmemoryBlockAdd(t *testing.T) {
|
func TestInmemoryBlockAdd(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
|
|
||||||
var ib inmemoryBlock
|
var ib inmemoryBlock
|
||||||
|
|
||||||
for i := 0; i < 30; i++ {
|
for i := 0; i < 30; i++ {
|
||||||
|
@ -42,7 +43,7 @@ func TestInmemoryBlockAdd(t *testing.T) {
|
||||||
|
|
||||||
// Fill ib.
|
// Fill ib.
|
||||||
for j := 0; j < i*100+1; j++ {
|
for j := 0; j < i*100+1; j++ {
|
||||||
s := getRandomBytes()
|
s := getRandomBytes(r)
|
||||||
if !ib.Add(s) {
|
if !ib.Add(s) {
|
||||||
// ib is full.
|
// ib is full.
|
||||||
break
|
break
|
||||||
|
@ -69,6 +70,7 @@ func TestInmemoryBlockAdd(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInmemoryBlockSort(t *testing.T) {
|
func TestInmemoryBlockSort(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
var ib inmemoryBlock
|
var ib inmemoryBlock
|
||||||
|
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
|
@ -77,8 +79,8 @@ func TestInmemoryBlockSort(t *testing.T) {
|
||||||
ib.Reset()
|
ib.Reset()
|
||||||
|
|
||||||
// Fill ib.
|
// Fill ib.
|
||||||
for j := 0; j < rand.Intn(1500); j++ {
|
for j := 0; j < r.Intn(1500); j++ {
|
||||||
s := getRandomBytes()
|
s := getRandomBytes(r)
|
||||||
if !ib.Add(s) {
|
if !ib.Add(s) {
|
||||||
// ib is full.
|
// ib is full.
|
||||||
break
|
break
|
||||||
|
@ -109,6 +111,7 @@ func TestInmemoryBlockSort(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInmemoryBlockMarshalUnmarshal(t *testing.T) {
|
func TestInmemoryBlockMarshalUnmarshal(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
var ib, ib2 inmemoryBlock
|
var ib, ib2 inmemoryBlock
|
||||||
var sb storageBlock
|
var sb storageBlock
|
||||||
var firstItem, commonPrefix []byte
|
var firstItem, commonPrefix []byte
|
||||||
|
@ -121,9 +124,9 @@ func TestInmemoryBlockMarshalUnmarshal(t *testing.T) {
|
||||||
ib.Reset()
|
ib.Reset()
|
||||||
|
|
||||||
// Fill ib.
|
// Fill ib.
|
||||||
itemsCount := 2 * (rand.Intn(i+1) + 1)
|
itemsCount := 2 * (r.Intn(i+1) + 1)
|
||||||
for j := 0; j < itemsCount/2; j++ {
|
for j := 0; j < itemsCount/2; j++ {
|
||||||
s := getRandomBytes()
|
s := getRandomBytes(r)
|
||||||
s = []byte("prefix " + string(s))
|
s = []byte("prefix " + string(s))
|
||||||
if !ib.Add(s) {
|
if !ib.Add(s) {
|
||||||
// ib is full.
|
// ib is full.
|
||||||
|
@ -132,7 +135,7 @@ func TestInmemoryBlockMarshalUnmarshal(t *testing.T) {
|
||||||
items = append(items, string(s))
|
items = append(items, string(s))
|
||||||
totalLen += len(s)
|
totalLen += len(s)
|
||||||
|
|
||||||
s = getRandomBytes()
|
s = getRandomBytes(r)
|
||||||
if !ib.Add(s) {
|
if !ib.Add(s) {
|
||||||
// ib is full
|
// ib is full
|
||||||
break
|
break
|
||||||
|
@ -186,10 +189,8 @@ func TestInmemoryBlockMarshalUnmarshal(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRandomBytes() []byte {
|
func getRandomBytes(r *rand.Rand) []byte {
|
||||||
rndLock.Lock()
|
iv, ok := quick.Value(bytesType, r)
|
||||||
iv, ok := quick.Value(bytesType, rnd)
|
|
||||||
rndLock.Unlock()
|
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Panicf("error in quick.Value when generating random string")
|
logger.Panicf("error in quick.Value when generating random string")
|
||||||
}
|
}
|
||||||
|
@ -197,8 +198,3 @@ func getRandomBytes() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
var bytesType = reflect.TypeOf([]byte(nil))
|
var bytesType = reflect.TypeOf([]byte(nil))
|
||||||
|
|
||||||
var (
|
|
||||||
rnd = rand.New(rand.NewSource(1))
|
|
||||||
rndLock sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
|
@ -23,8 +23,10 @@ func TestMergeBlockStreams(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultilevelMerge(t *testing.T) {
|
func TestMultilevelMerge(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
|
|
||||||
// Prepare blocks to merge.
|
// Prepare blocks to merge.
|
||||||
bsrs, items := newTestInmemoryBlockStreamReaders(10, 4000)
|
bsrs, items := newTestInmemoryBlockStreamReaders(r, 10, 4000)
|
||||||
var itemsMerged uint64
|
var itemsMerged uint64
|
||||||
|
|
||||||
// First level merge
|
// First level merge
|
||||||
|
@ -70,7 +72,8 @@ func TestMultilevelMerge(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMergeForciblyStop(t *testing.T) {
|
func TestMergeForciblyStop(t *testing.T) {
|
||||||
bsrs, _ := newTestInmemoryBlockStreamReaders(20, 4000)
|
r := rand.New(rand.NewSource(1))
|
||||||
|
bsrs, _ := newTestInmemoryBlockStreamReaders(r, 20, 4000)
|
||||||
var dstIP inmemoryPart
|
var dstIP inmemoryPart
|
||||||
var bsw blockStreamWriter
|
var bsw blockStreamWriter
|
||||||
bsw.InitFromInmemoryPart(&dstIP, 1)
|
bsw.InitFromInmemoryPart(&dstIP, 1)
|
||||||
|
@ -88,16 +91,18 @@ func TestMergeForciblyStop(t *testing.T) {
|
||||||
func testMergeBlockStreams(t *testing.T, blocksToMerge, maxItemsPerBlock int) {
|
func testMergeBlockStreams(t *testing.T, blocksToMerge, maxItemsPerBlock int) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
if err := testMergeBlockStreamsSerial(blocksToMerge, maxItemsPerBlock); err != nil {
|
r := rand.New(rand.NewSource(1))
|
||||||
|
if err := testMergeBlockStreamsSerial(r, blocksToMerge, maxItemsPerBlock); err != nil {
|
||||||
t.Fatalf("unexpected error in serial test: %s", err)
|
t.Fatalf("unexpected error in serial test: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const concurrency = 3
|
const concurrency = 3
|
||||||
ch := make(chan error, concurrency)
|
ch := make(chan error, concurrency)
|
||||||
for i := 0; i < concurrency; i++ {
|
for i := 0; i < concurrency; i++ {
|
||||||
go func() {
|
go func(n int) {
|
||||||
ch <- testMergeBlockStreamsSerial(blocksToMerge, maxItemsPerBlock)
|
rLocal := rand.New(rand.NewSource(int64(n)))
|
||||||
}()
|
ch <- testMergeBlockStreamsSerial(rLocal, blocksToMerge, maxItemsPerBlock)
|
||||||
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < concurrency; i++ {
|
for i := 0; i < concurrency; i++ {
|
||||||
|
@ -112,9 +117,9 @@ func testMergeBlockStreams(t *testing.T, blocksToMerge, maxItemsPerBlock int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMergeBlockStreamsSerial(blocksToMerge, maxItemsPerBlock int) error {
|
func testMergeBlockStreamsSerial(r *rand.Rand, blocksToMerge, maxItemsPerBlock int) error {
|
||||||
// Prepare blocks to merge.
|
// Prepare blocks to merge.
|
||||||
bsrs, items := newTestInmemoryBlockStreamReaders(blocksToMerge, maxItemsPerBlock)
|
bsrs, items := newTestInmemoryBlockStreamReaders(r, blocksToMerge, maxItemsPerBlock)
|
||||||
|
|
||||||
// Merge blocks.
|
// Merge blocks.
|
||||||
var itemsMerged uint64
|
var itemsMerged uint64
|
||||||
|
@ -175,14 +180,14 @@ func testCheckItems(dstIP *inmemoryPart, items []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestInmemoryBlockStreamReaders(blocksCount, maxItemsPerBlock int) ([]*blockStreamReader, []string) {
|
func newTestInmemoryBlockStreamReaders(r *rand.Rand, blocksCount, maxItemsPerBlock int) ([]*blockStreamReader, []string) {
|
||||||
var items []string
|
var items []string
|
||||||
var bsrs []*blockStreamReader
|
var bsrs []*blockStreamReader
|
||||||
for i := 0; i < blocksCount; i++ {
|
for i := 0; i < blocksCount; i++ {
|
||||||
var ib inmemoryBlock
|
var ib inmemoryBlock
|
||||||
itemsPerBlock := rand.Intn(maxItemsPerBlock) + 1
|
itemsPerBlock := r.Intn(maxItemsPerBlock) + 1
|
||||||
for j := 0; j < itemsPerBlock; j++ {
|
for j := 0; j < itemsPerBlock; j++ {
|
||||||
item := getRandomBytes()
|
item := getRandomBytes(r)
|
||||||
if !ib.Add(item) {
|
if !ib.Add(item) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPartSearch(t *testing.T) {
|
func TestPartSearch(t *testing.T) {
|
||||||
p, items, err := newTestPart(10, 4000)
|
r := rand.New(rand.NewSource(1))
|
||||||
|
p, items, err := newTestPart(r, 10, 4000)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot create test part: %s", err)
|
t.Fatalf("cannot create test part: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("serial", func(t *testing.T) {
|
t.Run("serial", func(t *testing.T) {
|
||||||
if err := testPartSearchSerial(p, items); err != nil {
|
if err := testPartSearchSerial(r, p, items); err != nil {
|
||||||
t.Fatalf("error in serial part search test: %s", err)
|
t.Fatalf("error in serial part search test: %s", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -31,9 +32,10 @@ func testPartSearchConcurrent(p *part, items []string) error {
|
||||||
const goroutinesCount = 5
|
const goroutinesCount = 5
|
||||||
ch := make(chan error, goroutinesCount)
|
ch := make(chan error, goroutinesCount)
|
||||||
for i := 0; i < goroutinesCount; i++ {
|
for i := 0; i < goroutinesCount; i++ {
|
||||||
go func() {
|
go func(n int) {
|
||||||
ch <- testPartSearchSerial(p, items)
|
rLocal := rand.New(rand.NewSource(int64(n)))
|
||||||
}()
|
ch <- testPartSearchSerial(rLocal, p, items)
|
||||||
|
}(i)
|
||||||
}
|
}
|
||||||
for i := 0; i < goroutinesCount; i++ {
|
for i := 0; i < goroutinesCount; i++ {
|
||||||
select {
|
select {
|
||||||
|
@ -48,7 +50,7 @@ func testPartSearchConcurrent(p *part, items []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPartSearchSerial(p *part, items []string) error {
|
func testPartSearchSerial(r *rand.Rand, p *part, items []string) error {
|
||||||
var ps partSearch
|
var ps partSearch
|
||||||
|
|
||||||
ps.Init(p)
|
ps.Init(p)
|
||||||
|
@ -88,7 +90,7 @@ func testPartSearchSerial(p *part, items []string) error {
|
||||||
|
|
||||||
// Search for inner items
|
// Search for inner items
|
||||||
for loop := 0; loop < 100; loop++ {
|
for loop := 0; loop < 100; loop++ {
|
||||||
idx := rand.Intn(len(items))
|
idx := r.Intn(len(items))
|
||||||
k = append(k[:0], items[idx]...)
|
k = append(k[:0], items[idx]...)
|
||||||
ps.Seek(k)
|
ps.Seek(k)
|
||||||
n := sort.Search(len(items), func(i int) bool {
|
n := sort.Search(len(items), func(i int) bool {
|
||||||
|
@ -143,8 +145,8 @@ func testPartSearchSerial(p *part, items []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestPart(blocksCount, maxItemsPerBlock int) (*part, []string, error) {
|
func newTestPart(r *rand.Rand, blocksCount, maxItemsPerBlock int) (*part, []string, error) {
|
||||||
bsrs, items := newTestInmemoryBlockStreamReaders(blocksCount, maxItemsPerBlock)
|
bsrs, items := newTestInmemoryBlockStreamReaders(r, blocksCount, maxItemsPerBlock)
|
||||||
|
|
||||||
var itemsMerged uint64
|
var itemsMerged uint64
|
||||||
var ip inmemoryPart
|
var ip inmemoryPart
|
||||||
|
|
|
@ -27,7 +27,8 @@ func TestTableSearchSerial(t *testing.T) {
|
||||||
const itemsCount = 1e5
|
const itemsCount = 1e5
|
||||||
|
|
||||||
items := func() []string {
|
items := func() []string {
|
||||||
tb, items, err := newTestTable(path, itemsCount)
|
r := rand.New(rand.NewSource(1))
|
||||||
|
tb, items, err := newTestTable(r, path, itemsCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot create test table: %s", err)
|
t.Fatalf("cannot create test table: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +64,8 @@ func TestTableSearchConcurrent(t *testing.T) {
|
||||||
|
|
||||||
const itemsCount = 1e5
|
const itemsCount = 1e5
|
||||||
items := func() []string {
|
items := func() []string {
|
||||||
tb, items, err := newTestTable(path, itemsCount)
|
r := rand.New(rand.NewSource(2))
|
||||||
|
tb, items, err := newTestTable(r, path, itemsCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot create test table: %s", err)
|
t.Fatalf("cannot create test table: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -148,7 +150,7 @@ func testTableSearchSerial(tb *Table, items []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestTable(path string, itemsCount int) (*Table, []string, error) {
|
func newTestTable(r *rand.Rand, path string, itemsCount int) (*Table, []string, error) {
|
||||||
var flushes uint64
|
var flushes uint64
|
||||||
flushCallback := func() {
|
flushCallback := func() {
|
||||||
atomic.AddUint64(&flushes, 1)
|
atomic.AddUint64(&flushes, 1)
|
||||||
|
@ -160,7 +162,7 @@ func newTestTable(path string, itemsCount int) (*Table, []string, error) {
|
||||||
}
|
}
|
||||||
items := make([]string, itemsCount)
|
items := make([]string, itemsCount)
|
||||||
for i := 0; i < itemsCount; i++ {
|
for i := 0; i < itemsCount; i++ {
|
||||||
item := fmt.Sprintf("%d:%d", rand.Intn(1e9), i)
|
item := fmt.Sprintf("%d:%d", r.Intn(1e9), i)
|
||||||
tb.AddItems([][]byte{[]byte(item)})
|
tb.AddItems([][]byte{[]byte(item)})
|
||||||
items[i] = item
|
items[i] = item
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ func BenchmarkTableSearch(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchmarkTableSearch(b *testing.B, itemsCount int) {
|
func benchmarkTableSearch(b *testing.B, itemsCount int) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
|
|
||||||
path := fmt.Sprintf("BenchmarkTableSearch-%d", itemsCount)
|
path := fmt.Sprintf("BenchmarkTableSearch-%d", itemsCount)
|
||||||
if err := os.RemoveAll(path); err != nil {
|
if err := os.RemoveAll(path); err != nil {
|
||||||
b.Fatalf("cannot remove %q: %s", path, err)
|
b.Fatalf("cannot remove %q: %s", path, err)
|
||||||
|
@ -25,7 +27,7 @@ func benchmarkTableSearch(b *testing.B, itemsCount int) {
|
||||||
_ = os.RemoveAll(path)
|
_ = os.RemoveAll(path)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tb, items, err := newTestTable(path, itemsCount)
|
tb, items, err := newTestTable(r, path, itemsCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot create test table at %q with %d items: %w", path, itemsCount, err))
|
panic(fmt.Errorf("cannot create test table at %q with %d items: %w", path, itemsCount, err))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +54,7 @@ func benchmarkTableSearch(b *testing.B, itemsCount int) {
|
||||||
})
|
})
|
||||||
|
|
||||||
randKeys := append([][]byte{}, keys...)
|
randKeys := append([][]byte{}, keys...)
|
||||||
rand.Shuffle(len(randKeys), func(i, j int) {
|
r.Shuffle(len(randKeys), func(i, j int) {
|
||||||
randKeys[i], randKeys[j] = randKeys[j], randKeys[i]
|
randKeys[i], randKeys[j] = randKeys[j], randKeys[i]
|
||||||
})
|
})
|
||||||
b.Run("random-keys-exact", func(b *testing.B) {
|
b.Run("random-keys-exact", func(b *testing.B) {
|
||||||
|
@ -81,11 +83,12 @@ func benchmarkTableSearchKeysExt(b *testing.B, tb *Table, keys [][]byte, stripSu
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.SetBytes(int64(searchKeysCount * rowsToScan))
|
b.SetBytes(int64(searchKeysCount * rowsToScan))
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
var ts TableSearch
|
var ts TableSearch
|
||||||
ts.Init(tb)
|
ts.Init(tb)
|
||||||
defer ts.MustClose()
|
defer ts.MustClose()
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
startIdx := rand.Intn(len(keys) - searchKeysCount)
|
startIdx := r.Intn(len(keys) - searchKeysCount)
|
||||||
searchKeys := keys[startIdx : startIdx+searchKeysCount]
|
searchKeys := keys[startIdx : startIdx+searchKeysCount]
|
||||||
for i, key := range searchKeys {
|
for i, key := range searchKeys {
|
||||||
searchKey := key
|
searchKey := key
|
||||||
|
|
|
@ -3,6 +3,7 @@ package mergeset
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -61,6 +62,7 @@ func TestTableOpenMultipleTimes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTableAddItemsSerial(t *testing.T) {
|
func TestTableAddItemsSerial(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
const path = "TestTableAddItemsSerial"
|
const path = "TestTableAddItemsSerial"
|
||||||
if err := os.RemoveAll(path); err != nil {
|
if err := os.RemoveAll(path); err != nil {
|
||||||
t.Fatalf("cannot remove %q: %s", path, err)
|
t.Fatalf("cannot remove %q: %s", path, err)
|
||||||
|
@ -80,7 +82,7 @@ func TestTableAddItemsSerial(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemsCount = 10e3
|
const itemsCount = 10e3
|
||||||
testAddItemsSerial(tb, itemsCount)
|
testAddItemsSerial(r, tb, itemsCount)
|
||||||
|
|
||||||
// Verify items count after pending items flush.
|
// Verify items count after pending items flush.
|
||||||
tb.DebugFlush()
|
tb.DebugFlush()
|
||||||
|
@ -105,16 +107,16 @@ func TestTableAddItemsSerial(t *testing.T) {
|
||||||
t.Fatalf("cannot open %q: %s", path, err)
|
t.Fatalf("cannot open %q: %s", path, err)
|
||||||
}
|
}
|
||||||
const moreItemsCount = itemsCount * 3
|
const moreItemsCount = itemsCount * 3
|
||||||
testAddItemsSerial(tb, moreItemsCount)
|
testAddItemsSerial(r, tb, moreItemsCount)
|
||||||
tb.MustClose()
|
tb.MustClose()
|
||||||
|
|
||||||
// Re-open the table and verify itemsCount again.
|
// Re-open the table and verify itemsCount again.
|
||||||
testReopenTable(t, path, itemsCount+moreItemsCount)
|
testReopenTable(t, path, itemsCount+moreItemsCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAddItemsSerial(tb *Table, itemsCount int) {
|
func testAddItemsSerial(r *rand.Rand, tb *Table, itemsCount int) {
|
||||||
for i := 0; i < itemsCount; i++ {
|
for i := 0; i < itemsCount; i++ {
|
||||||
item := getRandomBytes()
|
item := getRandomBytes(r)
|
||||||
if len(item) > maxInmemoryBlockSize {
|
if len(item) > maxInmemoryBlockSize {
|
||||||
item = item[:maxInmemoryBlockSize]
|
item = item[:maxInmemoryBlockSize]
|
||||||
}
|
}
|
||||||
|
@ -263,16 +265,17 @@ func testAddItemsConcurrent(tb *Table, itemsCount int) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < goroutinesCount; i++ {
|
for i := 0; i < goroutinesCount; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func(n int) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
r := rand.New(rand.NewSource(int64(n)))
|
||||||
for range workCh {
|
for range workCh {
|
||||||
item := getRandomBytes()
|
item := getRandomBytes(r)
|
||||||
if len(item) > maxInmemoryBlockSize {
|
if len(item) > maxInmemoryBlockSize {
|
||||||
item = item[:maxInmemoryBlockSize]
|
item = item[:maxInmemoryBlockSize]
|
||||||
}
|
}
|
||||||
tb.AddItems([][]byte{item})
|
tb.AddItems([][]byte{item})
|
||||||
}
|
}
|
||||||
}()
|
}(i)
|
||||||
}
|
}
|
||||||
for i := 0; i < itemsCount; i++ {
|
for i := 0; i < itemsCount; i++ {
|
||||||
workCh <- i
|
workCh <- i
|
||||||
|
|
Loading…
Reference in a new issue