Line data Source code
1 : // Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use
2 : // of this source code is governed by a BSD-style license that can be found in
3 : // the LICENSE file.
4 :
5 : package metamorphic
6 :
7 : import "github.com/cockroachdb/pebble/internal/randvar"
8 :
9 : type opType int
10 :
11 : const (
12 : batchAbort opType = iota
13 : batchCommit
14 : dbCheckpoint
15 : dbClose
16 : dbCompact
17 : dbFlush
18 : dbRatchetFormatMajorVersion
19 : dbRestart
20 : iterClose
21 : iterFirst
22 : iterLast
23 : iterNext
24 : iterNextWithLimit
25 : iterNextPrefix
26 : iterPrev
27 : iterPrevWithLimit
28 : iterSeekGE
29 : iterSeekGEWithLimit
30 : iterSeekLT
31 : iterSeekLTWithLimit
32 : iterSeekPrefixGE
33 : iterSetBounds
34 : iterSetOptions
35 : newBatch
36 : newIndexedBatch
37 : newIter
38 : newIterUsingClone
39 : newSnapshot
40 : readerGet
41 : snapshotClose
42 : writerApply
43 : writerDelete
44 : writerDeleteRange
45 : writerIngest
46 : writerMerge
47 : writerRangeKeyDelete
48 : writerRangeKeySet
49 : writerRangeKeyUnset
50 : writerSet
51 : writerSingleDelete
52 : )
53 :
54 : type config struct {
55 : // Weights for the operation mix to generate. ops[i] corresponds to the
56 : // weight for opType(i).
57 : ops []int
58 :
59 : // newPrefix configures the probability that when generating a new user key,
60 : // the generated key uses a new key prefix rather than an existing prefix
61 : // with a suffix.
62 : newPrefix float64
63 : // writeSuffixDist defines the distribution of key suffixes during writing.
64 : // It's a dynamic randvar to roughly emulate workloads with MVCC timestamps,
65 : // skewing towards most recent timestamps.
66 : writeSuffixDist randvar.Dynamic
67 :
68 : // TODO(peter): unimplemented
69 : // keyDist randvar.Dynamic
70 : // keySizeDist randvar.Static
71 : // valueSizeDist randvar.Static
72 : // updateFrac float64
73 : // lowerBoundFrac float64
74 : // upperBoundFrac float64
75 : }
76 :
77 1 : func defaultConfig() config {
78 1 : return config{
79 1 : // dbClose is not in this list since it is deterministically generated once, at the end of the test.
80 1 : ops: []int{
81 1 : batchAbort: 5,
82 1 : batchCommit: 5,
83 1 : dbCheckpoint: 1,
84 1 : dbCompact: 1,
85 1 : dbFlush: 2,
86 1 : dbRatchetFormatMajorVersion: 1,
87 1 : dbRestart: 2,
88 1 : iterClose: 5,
89 1 : iterFirst: 100,
90 1 : iterLast: 100,
91 1 : iterNext: 100,
92 1 : iterNextWithLimit: 20,
93 1 : iterNextPrefix: 20,
94 1 : iterPrev: 100,
95 1 : iterPrevWithLimit: 20,
96 1 : iterSeekGE: 100,
97 1 : iterSeekGEWithLimit: 20,
98 1 : iterSeekLT: 100,
99 1 : iterSeekLTWithLimit: 20,
100 1 : iterSeekPrefixGE: 100,
101 1 : iterSetBounds: 100,
102 1 : iterSetOptions: 10,
103 1 : newBatch: 5,
104 1 : newIndexedBatch: 5,
105 1 : newIter: 10,
106 1 : newIterUsingClone: 5,
107 1 : newSnapshot: 10,
108 1 : readerGet: 100,
109 1 : snapshotClose: 10,
110 1 : writerApply: 10,
111 1 : writerDelete: 100,
112 1 : writerDeleteRange: 50,
113 1 : writerIngest: 100,
114 1 : writerMerge: 100,
115 1 : writerRangeKeySet: 10,
116 1 : writerRangeKeyUnset: 10,
117 1 : writerRangeKeyDelete: 5,
118 1 : writerSet: 100,
119 1 : writerSingleDelete: 50,
120 1 : },
121 1 : // Use a new prefix 75% of the time (and 25% of the time use an existing
122 1 : // prefix with an alternative suffix).
123 1 : newPrefix: 0.75,
124 1 : // Use a skewed distribution of suffixes to mimic MVCC timestamps. The
125 1 : // range will be widened whenever a suffix is found to already be in use
126 1 : // for a particular prefix.
127 1 : writeSuffixDist: mustDynamic(randvar.NewSkewedLatest(0, 1, 0.99)),
128 1 : }
129 1 : }
130 :
131 1 : func mustDynamic(dyn randvar.Dynamic, err error) randvar.Dynamic {
132 1 : if err != nil {
133 0 : panic(err)
134 : }
135 1 : return dyn
136 : }
|