+ * It inserts a fixed number of records (inserts and deletes) in a loop and measures the time it takes to handle all the records. It uses a test harness, not the full Flink job. + *
+ The benchmark has the following parameters: +
{@code
+Benchmark (hasUpsertKey) (payloadSize) (retractDelay) (retractPercentage) (stateBackend) (sumVersion) Mode Cnt Score Error Units
+SinkUpsertMaterializerBenchmark.run false 100 1 100 HEAP V1 thrpt 4138.808 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 1 100 ROCKSDB V1 thrpt 284.055 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 10 100 HEAP V1 thrpt 3729.824 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 10 100 ROCKSDB V1 thrpt 205.047 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 100 100 HEAP V1 thrpt 4137.591 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 100 100 ROCKSDB V1 thrpt 80.406 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 200 100 HEAP V1 thrpt 1886.574 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 200 100 ROCKSDB V1 thrpt 30.935 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 1000 100 HEAP V1 thrpt 546.826 ops/ms
+SinkUpsertMaterializerBenchmark.run false 100 1000 100 ROCKSDB V1 thrpt 7.081 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 1 100 HEAP V1 thrpt 4006.263 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 1 100 ROCKSDB V1 thrpt 297.556 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 10 100 HEAP V1 thrpt 3240.089 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 10 100 ROCKSDB V1 thrpt 209.375 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 100 100 HEAP V1 thrpt 2131.445 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 100 100 ROCKSDB V1 thrpt 78.209 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 200 100 HEAP V1 thrpt 652.936 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 200 100 ROCKSDB V1 thrpt 29.674 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 1000 100 HEAP V1 thrpt 118.567 ops/ms
+SinkUpsertMaterializerBenchmark.run true 100 1000 100 ROCKSDB V1 thrpt 6.426 ops/ms
+ * }
+ */
+@OperationsPerInvocation(value = SinkUpsertMaterializerBenchmark.RECORDS_PER_INVOCATION)
+@SuppressWarnings("ConstantValue")
+public class SinkUpsertMaterializerBenchmark extends BenchmarkBase {
+
+ private static final int STREAM_KEY = 0;
+
+ public static void main(String[] args) throws RunnerException {
+ new Runner(new OptionsBuilder()
+ .verbosity(VerboseMode.NORMAL)
+ .include(".*" + SinkUpsertMaterializerBenchmark.class.getCanonicalName() + ".*")
+ .build()).run();
+ }
+
+ @Benchmark
+ public void run(SumBmState state) throws Exception {
+ for (long record = 0; record < state.numRecordsTotal; record++) {
+ state.harness.processElement(insertRecord(record, STREAM_KEY, state.payload));
+ if (state.shouldRetract(record)) {
+ state.harness.processElement(
+ deleteRecord(record - state.retractOffset, STREAM_KEY, state.payload));
+ }
+ }
+ }
+
+ protected static final int RECORDS_PER_INVOCATION = 10_000;
+
+ @State(Scope.Thread)
+ public static class SumBmState {
+
+ @Param({"false", "true"}) public boolean hasUpsertKey;
+
+ @Param({"HEAP", "ROCKSDB"}) public SumStateBackend stateBackend;
+
+ public int numRecordsTotal;
+
+ // larger payload amplifies any inefficiencies but slows down the benchmark; mostly affects rocksdb
+ @Param({"20"})
+ public int payloadSize;
+
+ // lower retraction percentage implies longer history, making retractions even harder (unless percentage = 0)
+ @Param("100")
+ public int retractPercentage;
+
+ // higher retraction delay leaves longer history, making retractions even harder (unless percentage = 0)
+ // for automated runs, reduce the run time (and the data points) to the most common cases
+ @Param({"1", "1000"})
+ // for comparison, the following values might be useful:
+ // @Param({"1", "10", "100", "200", "1000"})
+ public int retractDelay;
+
+ // the lower the value, the closer to the end of the list is the element to retract, the harder for V1 to find the element
+ public long retractOffset;
+
+ public String payload;
+
+ public KeyedOneInputStreamOperatorTestHarness