Skip to content

Commit eaa6945

Browse files
Fix scan length distribution for YCSB (#466)
## TL;DR This patch changes the distribution of scan lengths in YCSB from a Zipfian distribution to a uniform distribution. ## Background The default distribution of scan lengths in YCSB Workload E is uniform [^1] [^2] [^3]. The current implementation uses Zipfian distribution with a specified skew factor, which should be avoided for fair evaluation of scan performance. <img width="1458" alt="Screenshot 2024-02-14 at 15 48 10" src="https://github.com/cmu-db/benchbase/assets/1114146/f8761826-96b7-403b-87a4-4bafad9e6c4f"> [^1]: https://github.com/brianfrankcooper/YCSB/blob/ce3eb9/workloads/workloade#L44 [^2]: https://github.com/brianfrankcooper/YCSB/blob/ce3eb9/core/src/main/java/site/ycsb/workloads/CoreWorkload.java#L536 [^3]: https://doi.org/10.1145/1807128.1807152 --------- Co-authored-by: Andy Pavlo <[email protected]>
1 parent a7b07ce commit eaa6945

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.oltpbenchmark.api.Worker;
2424
import com.oltpbenchmark.benchmarks.ycsb.procedures.*;
2525
import com.oltpbenchmark.distributions.CounterGenerator;
26+
import com.oltpbenchmark.distributions.UniformGenerator;
2627
import com.oltpbenchmark.distributions.ZipfianGenerator;
2728
import com.oltpbenchmark.types.TransactionStatus;
2829
import com.oltpbenchmark.util.TextGenerator;
@@ -39,7 +40,7 @@ class YCSBWorker extends Worker<YCSBBenchmark> {
3940

4041
private final ZipfianGenerator readRecord;
4142
private static CounterGenerator insertRecord;
42-
private final ZipfianGenerator randScan;
43+
private final UniformGenerator randScan;
4344

4445
private final char[] data;
4546
private final String[] params = new String[YCSBConstants.NUM_FIELDS];
@@ -58,7 +59,7 @@ public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count)
5859
this.readRecord =
5960
new ZipfianGenerator(
6061
rng(), init_record_count, benchmarkModule.skewFactor); // pool for read keys
61-
this.randScan = new ZipfianGenerator(rng(), YCSBConstants.MAX_SCAN, benchmarkModule.skewFactor);
62+
this.randScan = new UniformGenerator(1, YCSBConstants.MAX_SCAN);
6263

6364
synchronized (YCSBWorker.class) {
6465
// We must know where to start inserting
@@ -100,41 +101,35 @@ protected TransactionStatus executeWork(Connection conn, TransactionType nextTra
100101
}
101102

102103
private void updateRecord(Connection conn) throws SQLException {
103-
104104
int keyname = readRecord.nextInt();
105105
this.buildParameters();
106106
this.procUpdateRecord.run(conn, keyname, this.params);
107107
}
108108

109109
private void scanRecord(Connection conn) throws SQLException {
110-
111110
int keyname = readRecord.nextInt();
112111
int count = randScan.nextInt();
113112
this.procScanRecord.run(conn, keyname, count, new ArrayList<>());
114113
}
115114

116115
private void readRecord(Connection conn) throws SQLException {
117-
118116
int keyname = readRecord.nextInt();
119117
this.procReadRecord.run(conn, keyname, this.results);
120118
}
121119

122120
private void readModifyWriteRecord(Connection conn) throws SQLException {
123-
124121
int keyname = readRecord.nextInt();
125122
this.buildParameters();
126123
this.procReadModifyWriteRecord.run(conn, keyname, this.params, this.results);
127124
}
128125

129126
private void insertRecord(Connection conn) throws SQLException {
130-
131127
int keyname = insertRecord.nextInt();
132128
this.buildParameters();
133129
this.procInsertRecord.run(conn, keyname, this.params);
134130
}
135131

136132
private void deleteRecord(Connection conn) throws SQLException {
137-
138133
int keyname = readRecord.nextInt();
139134
this.procDeleteRecord.run(conn, keyname);
140135
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.oltpbenchmark.distributions;
2+
3+
import java.util.concurrent.ThreadLocalRandom;
4+
5+
public class UniformGenerator extends IntegerGenerator {
6+
int min;
7+
int max;
8+
9+
/**
10+
* Create a uniformly distributed random number generator for items.
11+
*
12+
* @param items Number of items.
13+
*/
14+
public UniformGenerator(int items) {
15+
this(0, items - 1);
16+
}
17+
18+
/**
19+
* Create a uniformly distributed random number generator for items between min and max
20+
* (inclusive).
21+
*
22+
* @param min Smallest integer to generate in the sequence.
23+
* @param max Largest integer to generate in the sequence.
24+
*/
25+
public UniformGenerator(int min, int max) {
26+
this.min = min;
27+
this.max = max;
28+
}
29+
30+
@Override
31+
public int nextInt() {
32+
return ThreadLocalRandom.current().nextInt(this.min, this.max + 1);
33+
}
34+
35+
@Override
36+
public double mean() {
37+
return (this.max + this.min) / 2.0;
38+
}
39+
}

0 commit comments

Comments
 (0)