diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineAppReport.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineAppReport.java
index 678609d..c04d759 100755
--- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineAppReport.java
+++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineAppReport.java
@@ -36,13 +36,15 @@
import com.tsurugidb.benchmark.costaccounting.online.periodic.BenchPeriodicUpdateStockTask;
import com.tsurugidb.benchmark.costaccounting.online.task.BenchOnlineTask;
import com.tsurugidb.benchmark.costaccounting.util.BenchConst;
+import com.tsurugidb.benchmark.costaccounting.util.PathUtil;
public class OnlineAppReport {
private static final Logger LOG = LoggerFactory.getLogger(OnlineAppReport.class);
private static final String HEADER1 = "# Online Application Report";
- private final StringBuilder onlineAppReport = new StringBuilder(HEADER1 + "\n");
+ private final StringBuilder onlineAppReport = new StringBuilder(2048).append(HEADER1 + "\n");
+ private final StringBuilder csvReport = new StringBuilder(2048).append(OnlineTimeRecord.CSV_HEADER + "\n");
public void writeOnlineAppReport(OnlineConfig config, OnlineAppReportHeader title, Path onlineReportPath, long dedicatedTime, Path compareBaseFile) {
LOG.debug("Creating an online application report for {}", title);
@@ -57,6 +59,14 @@ public void writeOnlineAppReport(OnlineConfig config, OnlineAppReportHeader titl
} catch (IOException e) {
throw new UncheckedIOException(e.getMessage(), e);
}
+
+ Path csvReportPath = PathUtil.convertExt(onlineReportPath, "csv");
+ LOG.debug("Writing online application csv reports to {}", csvReportPath.toAbsolutePath());
+ try {
+ Files.writeString(csvReportPath, csvReport.toString());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e.getMessage(), e);
+ }
}
private String createOnlineAppReport(OnlineConfig config, OnlineAppReportHeader title, long dedicatedTime, Path compareBaseFile) {
@@ -150,6 +160,9 @@ private void cerateOnlineTimeReport(OnlineConfig config, StringBuilder sb, Strin
var record = OnlineTimeRecord.of(config, taskName, dedicatedTime, counter, compareBaseRecord);
sb.append(record);
sb.append("\n");
+
+ record.toCsv(csvReport);
+ csvReport.append("\n");
}
// compare base
diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineTimeRecord.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineTimeRecord.java
index 545d67d..9af111b 100755
--- a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineTimeRecord.java
+++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/online/command/OnlineTimeRecord.java
@@ -29,10 +29,17 @@ public class OnlineTimeRecord {
"| title | tx option | cover rate | dedicated time[ms] | numbers of txs | latency
avg[ms] | latency
min[ms] | latency
max[ms] | committed tx through put[task/s] |", //
"|-------|-----------|-----------:|-------------------:|---------------:|-------------------:|-------------------:|-------------------:|---------------------------------:|");
+ public static final String CSV_HEADER = "title, tx option, cover rate(config), cover rate, dedicated time[ms], numbers of txs," //
+ + " latency avg[ms], latency avg rate[%]," //
+ + " latency min[ms], latency min rate[%]" //
+ + " latency max[ms], latency max rate[%]" //
+ + " committed tx through put[task/s], committed tx through put rate[%]";
+
public static OnlineTimeRecord of(OnlineConfig config, String taskName, long dedicatedTime, BenchDbCounter counter, OnlineTimeRecord compareBaseRecord) {
var record = new OnlineTimeRecord();
record.taskName = taskName;
record.txOption = counter.getTxOptionDescription(taskName);
+ record.configCoverRate = config.getCoverRate();
record.coverRate = config.getCoverRateForReport(taskName);
record.dedicatedTime = dedicatedTime;
var time = counter.getTime(taskName, CounterName.TASK_SUCCESS);
@@ -100,6 +107,8 @@ private static double parseDouble(String s) {
return Double.parseDouble(s.replace(",", ""));
}
+ int configCoverRate;
+
String taskName;
String txOption;
String coverRate;
@@ -183,4 +192,56 @@ private String toString(ToDoubleFunction getter) {
}
return s;
}
+
+ public void toCsv(StringBuilder sb) {
+ sb.append(taskName);
+ sb.append(",");
+ sb.append(txOption.replace(',', ':'));
+ sb.append(",");
+ sb.append(configCoverRate);
+ sb.append(",");
+ sb.append(coverRate);
+
+ // dedicated time
+ sb.append(",");
+ sb.append(dedicatedTime);
+
+ {
+ // numbers of txs
+ sb.append(",");
+ sb.append(numbersOfTxs);
+
+ // latency
+ sb.append(",");
+ appendCsv(sb, OnlineTimeRecord::latencyAvg);
+ sb.append(",");
+ appendCsv(sb, OnlineTimeRecord::latencyMin);
+ sb.append(",");
+ appendCsv(sb, OnlineTimeRecord::latencyMax);
+
+ // committed tx through put
+ sb.append(",");
+ appendCsv(sb, OnlineTimeRecord::committedTxThroughPut);
+ }
+ }
+
+ private void appendCsv(StringBuilder sb, ToDoubleFunction getter) {
+ double value = getter.applyAsDouble(this);
+ if (Double.isNaN(value)) {
+ sb.append("-,-");
+ return;
+ }
+ sb.append(String.format("%.3f", value));
+
+ sb.append(",");
+ if (this.compareBaseRecord != null) {
+ double base = getter.applyAsDouble(compareBaseRecord);
+ if (Double.isNaN(base) || base == 0) {
+ sb.append("-");
+ }
+ sb.append(String.format("%.2f", value / base * 100)); // [%]
+ } else {
+ sb.append("-");
+ }
+ }
}
diff --git a/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/PathUtil.java b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/PathUtil.java
new file mode 100755
index 0000000..f4b8836
--- /dev/null
+++ b/java/cost-accounting-benchmark/src/main/java/com/tsurugidb/benchmark/costaccounting/util/PathUtil.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023-2024 Project Tsurugi.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.tsurugidb.benchmark.costaccounting.util;
+
+import java.nio.file.Path;
+
+public class PathUtil {
+
+ public static Path convertExt(Path path, String newExt) {
+ String fileName;
+ {
+ Path fileNamePath = path.getFileName();
+ if (fileNamePath != null) {
+ fileName = fileNamePath.toString();
+ } else {
+ fileName = "";
+ }
+ }
+
+ int n = fileName.lastIndexOf('.');
+ if (n >= 0) {
+ fileName = fileName.substring(0, n) + "." + newExt;
+ } else {
+ fileName += "." + newExt;
+ }
+
+ Path parent = path.getParent();
+ if (parent != null) {
+ return parent.resolve(fileName);
+ } else {
+ return Path.of(fileName);
+ }
+ }
+}