Skip to content

Commit c5a2e25

Browse files
committed
cockroachkvs: export RandomKVs
Export the utility used to generate random CRDB KVs.
1 parent 4385cd5 commit c5a2e25

File tree

4 files changed

+140
-126
lines changed

4 files changed

+140
-126
lines changed

cockroachkvs/cockroachkvs_bench_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func BenchmarkRandSeekInSST(b *testing.B) {
6767
version: sstable.TableFormatPebblev6,
6868
},
6969
}
70-
keyCfg := keyGenConfig{
70+
keyCfg := KeyGenConfig{
7171
PrefixAlphabetLen: 26,
7272
RoachKeyLen: 12,
7373
PrefixLenShared: 4,
@@ -95,11 +95,11 @@ func benchmarkRandSeekInSST(
9595
b *testing.B,
9696
rng *rand.Rand,
9797
numKeys int,
98-
keyCfg keyGenConfig,
98+
keyCfg KeyGenConfig,
9999
valueLen int,
100100
writerOpts sstable.WriterOptions,
101101
) {
102-
keys, values := randomKVs(rng, numKeys, keyCfg, valueLen)
102+
keys, values := RandomKVs(rng, numKeys, keyCfg, valueLen)
103103
obj := &objstorage.MemObj{}
104104
w := sstable.NewWriter(obj, writerOpts)
105105
for i := range keys {
@@ -168,12 +168,12 @@ func benchmarkRandSeekInSST(
168168
func BenchmarkCockroachDataColBlockWriter(b *testing.B) {
169169
for _, cfg := range benchConfigs {
170170
b.Run(cfg.String(), func(b *testing.B) {
171-
benchmarkCockroachDataColBlockWriter(b, cfg.keyGenConfig, cfg.ValueLen)
171+
benchmarkCockroachDataColBlockWriter(b, cfg.KeyGenConfig, cfg.ValueLen)
172172
})
173173
}
174174
}
175175

176-
func benchmarkCockroachDataColBlockWriter(b *testing.B, keyConfig keyGenConfig, valueLen int) {
176+
func benchmarkCockroachDataColBlockWriter(b *testing.B, keyConfig KeyGenConfig, valueLen int) {
177177
const targetBlockSize = 32 << 10
178178
seed := uint64(time.Now().UnixNano())
179179
rng := rand.New(rand.NewPCG(0, seed))
@@ -198,7 +198,7 @@ func benchmarkCockroachDataColBlockWriter(b *testing.B, keyConfig keyGenConfig,
198198

199199
var benchConfigs = []benchConfig{
200200
{
201-
keyGenConfig: keyGenConfig{
201+
KeyGenConfig: KeyGenConfig{
202202
PrefixAlphabetLen: 8,
203203
RoachKeyLen: 8,
204204
PrefixLenShared: 4,
@@ -208,7 +208,7 @@ var benchConfigs = []benchConfig{
208208
ValueLen: 8,
209209
},
210210
{
211-
keyGenConfig: keyGenConfig{
211+
KeyGenConfig: KeyGenConfig{
212212
PrefixAlphabetLen: 8,
213213
RoachKeyLen: 128,
214214
PrefixLenShared: 64,
@@ -218,7 +218,7 @@ var benchConfigs = []benchConfig{
218218
ValueLen: 128,
219219
},
220220
{
221-
keyGenConfig: keyGenConfig{
221+
KeyGenConfig: KeyGenConfig{
222222
PrefixAlphabetLen: 26,
223223
RoachKeyLen: 1024,
224224
PrefixLenShared: 512,
@@ -282,12 +282,12 @@ func BenchmarkCockroachDataColBlockIterTransforms(b *testing.B) {
282282
}
283283

284284
type benchConfig struct {
285-
keyGenConfig
285+
KeyGenConfig
286286
ValueLen int
287287
}
288288

289289
func (cfg benchConfig) String() string {
290-
return fmt.Sprintf("%s,ValueLen=%d", cfg.keyGenConfig, cfg.ValueLen)
290+
return fmt.Sprintf("%s,ValueLen=%d", cfg.KeyGenConfig, cfg.ValueLen)
291291
}
292292

293293
func benchmarkCockroachDataColBlockIter(
@@ -298,7 +298,7 @@ func benchmarkCockroachDataColBlockIter(
298298
rng := rand.New(rand.NewPCG(0, seed))
299299
cfg.BaseWallTime = seed
300300

301-
serializedBlock, keys, _ := generateDataBlock(rng, targetBlockSize, cfg.keyGenConfig, cfg.ValueLen)
301+
serializedBlock, keys, _ := generateDataBlock(rng, targetBlockSize, cfg.KeyGenConfig, cfg.ValueLen)
302302

303303
var decoder colblk.DataBlockDecoder
304304
var it colblk.DataBlockIter

cockroachkvs/cockroachkvs_test.go

Lines changed: 6 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ func TestRandKeys(t *testing.T) {
316316
seed := uint64(1234)
317317
count := 10
318318
valueLen := 4
319-
cfg := keyGenConfig{
319+
cfg := KeyGenConfig{
320320
PrefixAlphabetLen: 8,
321321
PrefixLenShared: 4,
322322
RoachKeyLen: 8,
@@ -344,7 +344,7 @@ func TestRandKeys(t *testing.T) {
344344
switch d.Cmd {
345345
case "rand-kvs":
346346
var vals [][]byte
347-
keys, vals = randomKVs(rng, count, cfg, valueLen)
347+
keys, vals = RandomKVs(rng, count, cfg, valueLen)
348348
for i, key := range keys {
349349
fmt.Fprintf(&buf, "%s = %X\n", formatUserKey(key), vals[i])
350350
}
@@ -369,7 +369,7 @@ func TestCockroachDataColBlock(t *testing.T) {
369369
rng := rand.New(rand.NewPCG(0, seed))
370370

371371
for i := 0; i < 100; i++ {
372-
keyCfg := keyGenConfig{
372+
keyCfg := KeyGenConfig{
373373
PrefixAlphabetLen: 2 + rng.IntN(25),
374374
RoachKeyLen: 10 + int(rng.ExpFloat64()*10),
375375
AvgKeysPerPrefix: 1 + int(rng.ExpFloat64()*[]float64{1, 10, 100}[rng.IntN(3)]),
@@ -400,7 +400,7 @@ func TestCockroachDataColBlock(t *testing.T) {
400400
}
401401
}
402402

403-
func testCockroachDataColBlock(t *testing.T, seed uint64, keyCfg keyGenConfig) {
403+
func testCockroachDataColBlock(t *testing.T, seed uint64, keyCfg KeyGenConfig) {
404404
const targetBlockSize = 32 << 10
405405
rng := rand.New(rand.NewPCG(0, seed))
406406
valueLen := 1 + rng.IntN(300)
@@ -453,9 +453,9 @@ func testCockroachDataColBlock(t *testing.T, seed uint64, keyCfg keyGenConfig) {
453453
// parameters. Returns the serialized block data and the keys and values
454454
// written.
455455
func generateDataBlock(
456-
rng *rand.Rand, targetBlockSize int, cfg keyGenConfig, valueLen int,
456+
rng *rand.Rand, targetBlockSize int, cfg KeyGenConfig, valueLen int,
457457
) (data []byte, keys [][]byte, values [][]byte) {
458-
keys, values = randomKVs(rng, targetBlockSize/valueLen, cfg, valueLen)
458+
keys, values = RandomKVs(rng, targetBlockSize/valueLen, cfg, valueLen)
459459

460460
var w colblk.DataBlockEncoder
461461
w.Init(&KeySchema)
@@ -478,80 +478,6 @@ func (g getInternalValuer) GetInternalValueForPrefixAndValueHandle(
478478
return g(handle)
479479
}
480480

481-
// keyGenConfig configures the shape of the random keys generated.
482-
type keyGenConfig struct {
483-
PrefixAlphabetLen int // Number of bytes in the alphabet used for the prefix.
484-
PrefixLenShared int // Number of bytes shared by all key prefixes.
485-
RoachKeyLen int // Number of bytes in the prefix (without the 0 sentinel byte).
486-
AvgKeysPerPrefix int // Average number of keys (with varying suffixes) per prefix.
487-
BaseWallTime uint64 // Smallest MVCC WallTime.
488-
PercentLogical int // Percent of MVCC keys with non-zero MVCC logical time.
489-
PercentEmptySuffix int // Percent of keys with empty suffix.
490-
PercentLockSuffix int // Percent of keys with lock suffix.
491-
}
492-
493-
func (cfg keyGenConfig) String() string {
494-
return fmt.Sprintf(
495-
"AlphaLen=%d,Prefix=%d,Shared=%d,KeysPerPrefix=%d%s",
496-
cfg.PrefixAlphabetLen, cfg.RoachKeyLen, cfg.PrefixLenShared,
497-
cfg.AvgKeysPerPrefix,
498-
crstrings.If(cfg.PercentLogical != 0, fmt.Sprintf(",Logical=%d", cfg.PercentLogical)),
499-
)
500-
}
501-
502-
// randomKVs constructs count random KVs with the provided parameters.
503-
func randomKVs(rng *rand.Rand, count int, cfg keyGenConfig, valueLen int) (keys, vals [][]byte) {
504-
g := makeCockroachKeyGen(rng, cfg)
505-
sharedPrefix := make([]byte, cfg.PrefixLenShared)
506-
for i := 0; i < len(sharedPrefix); i++ {
507-
sharedPrefix[i] = byte(rng.IntN(cfg.PrefixAlphabetLen) + 'a')
508-
}
509-
510-
keys = make([][]byte, 0, count)
511-
for len(keys) < count {
512-
roachKey := g.randRoachKey(sharedPrefix)
513-
// We use the exponential distribution so that we occasionally have many
514-
// suffixes
515-
n := int(rng.ExpFloat64() * float64(cfg.AvgKeysPerPrefix))
516-
n = max(n, 1)
517-
for i := 0; i < n && len(keys) < count; i++ {
518-
if cfg.PercentEmptySuffix+cfg.PercentLockSuffix > 0 {
519-
if r := rng.IntN(100); r < cfg.PercentEmptySuffix+cfg.PercentLockSuffix {
520-
k := append(roachKey, 0)
521-
if r < cfg.PercentLockSuffix {
522-
// Generate a lock key suffix.
523-
for j := 0; j < engineKeyVersionLockTableLen; j++ {
524-
k = append(k, byte(g.rng.IntN(g.cfg.PrefixAlphabetLen)+'a'))
525-
}
526-
k = append(k, engineKeyVersionLockTableLen+1)
527-
}
528-
keys = append(keys, k)
529-
continue
530-
}
531-
}
532-
533-
wallTime, logicalTime := g.randTimestamp()
534-
k := makeMVCCKey(roachKey, wallTime, logicalTime)
535-
keys = append(keys, k)
536-
}
537-
}
538-
slices.SortFunc(keys, Compare)
539-
vals = make([][]byte, count)
540-
for i := range vals {
541-
v := make([]byte, valueLen)
542-
for j := range v {
543-
v[j] = byte(rng.Uint32())
544-
}
545-
vals[i] = v
546-
}
547-
return keys, vals
548-
}
549-
550-
func makeMVCCKey(roachKey []byte, wallTime uint64, logicalTime uint32) []byte {
551-
k := slices.Grow(slices.Clip(roachKey), MaxSuffixLen)
552-
return EncodeTimestamp(k, wallTime, logicalTime)
553-
}
554-
555481
// randomQueryKeys returns a slice of count random query keys. Each key has a
556482
// random prefix uniformly chosen from the distinct prefixes in writtenKeys and
557483
// a random timestamp.
@@ -581,35 +507,6 @@ func randomQueryKeys(
581507
return result
582508
}
583509

584-
type cockroachKeyGen struct {
585-
rng *rand.Rand
586-
cfg keyGenConfig
587-
}
588-
589-
func makeCockroachKeyGen(rng *rand.Rand, cfg keyGenConfig) cockroachKeyGen {
590-
return cockroachKeyGen{
591-
rng: rng,
592-
cfg: cfg,
593-
}
594-
}
595-
596-
func (g *cockroachKeyGen) randRoachKey(blockPrefix []byte) []byte {
597-
roachKey := make([]byte, 0, g.cfg.RoachKeyLen+MaxSuffixLen)
598-
roachKey = append(roachKey, blockPrefix...)
599-
for len(roachKey) < g.cfg.RoachKeyLen {
600-
roachKey = append(roachKey, byte(g.rng.IntN(g.cfg.PrefixAlphabetLen)+'a'))
601-
}
602-
return roachKey
603-
}
604-
605-
func (g *cockroachKeyGen) randTimestamp() (wallTime uint64, logicalTime uint32) {
606-
wallTime = g.cfg.BaseWallTime + g.rng.Uint64N(uint64(time.Hour))
607-
if g.cfg.PercentLogical > 0 && g.rng.IntN(100) < g.cfg.PercentLogical {
608-
logicalTime = g.rng.Uint32()
609-
}
610-
return wallTime, logicalTime
611-
}
612-
613510
// formatUserKey formats a user key in the format:
614511
//
615512
// <roach-key> [ @ <version-hex> ]

cockroachkvs/rowblk_bench_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ import (
1818
func BenchmarkCockroachDataRowBlockWriter(b *testing.B) {
1919
for _, cfg := range benchConfigs {
2020
b.Run(cfg.String(), func(b *testing.B) {
21-
benchmarkCockroachDataRowBlockWriter(b, cfg.keyGenConfig, cfg.ValueLen)
21+
benchmarkCockroachDataRowBlockWriter(b, cfg.KeyGenConfig, cfg.ValueLen)
2222
})
2323
}
2424
}
2525

26-
func benchmarkCockroachDataRowBlockWriter(b *testing.B, keyConfig keyGenConfig, valueLen int) {
26+
func benchmarkCockroachDataRowBlockWriter(b *testing.B, keyConfig KeyGenConfig, valueLen int) {
2727
const targetBlockSize = 32 << 10
2828
seed := uint64(time.Now().UnixNano())
2929
rng := rand.New(rand.NewPCG(0, seed))
30-
keys, values := randomKVs(rng, targetBlockSize/valueLen, keyConfig, valueLen)
30+
keys, values := RandomKVs(rng, targetBlockSize/valueLen, keyConfig, valueLen)
3131

3232
var w rowblk.Writer
3333
w.RestartInterval = 16
@@ -54,16 +54,16 @@ func benchmarkCockroachDataRowBlockWriter(b *testing.B, keyConfig keyGenConfig,
5454
func BenchmarkCockroachDataRowBlockIter(b *testing.B) {
5555
for _, cfg := range benchConfigs {
5656
b.Run(cfg.String(), func(b *testing.B) {
57-
benchmarkCockroachDataRowBlockIter(b, cfg.keyGenConfig, cfg.ValueLen)
57+
benchmarkCockroachDataRowBlockIter(b, cfg.KeyGenConfig, cfg.ValueLen)
5858
})
5959
}
6060
}
6161

62-
func benchmarkCockroachDataRowBlockIter(b *testing.B, keyConfig keyGenConfig, valueLen int) {
62+
func benchmarkCockroachDataRowBlockIter(b *testing.B, keyConfig KeyGenConfig, valueLen int) {
6363
const targetBlockSize = 32 << 10
6464
seed := uint64(time.Now().UnixNano())
6565
rng := rand.New(rand.NewPCG(0, seed))
66-
keys, values := randomKVs(rng, targetBlockSize/valueLen, keyConfig, valueLen)
66+
keys, values := RandomKVs(rng, targetBlockSize/valueLen, keyConfig, valueLen)
6767

6868
var w rowblk.Writer
6969
w.RestartInterval = 16

0 commit comments

Comments
 (0)