add percentile information if available
This commit is contained in:
@@ -3,6 +3,7 @@ package org.lucares.pdb.plot.api;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.lucares.pdb.api.Tags;
|
||||
@@ -27,4 +28,15 @@ public class AggregatorCollection {
|
||||
return Optional.ofNullable(aggregators.get(type));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends CustomAggregator> Optional<T> getAggregator(final Class<T> aggregatorType) {
|
||||
|
||||
for (final CustomAggregator aggregator : aggregators.values()) {
|
||||
if (Objects.equals(aggregator.getClass(), aggregatorType)) {
|
||||
return Optional.of((T) aggregator);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.lucares.collections.LongLongConsumer;
|
||||
import org.lucares.collections.LongLongHashMap;
|
||||
@@ -24,7 +24,7 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
||||
|
||||
private long maxValue = 0;
|
||||
|
||||
private final LinkedHashMap<Double, Long> percentiles = new LinkedHashMap<>(POINTS);
|
||||
private final Percentiles percentiles = new Percentiles(POINTS);
|
||||
|
||||
private final double stepSize;
|
||||
|
||||
@@ -49,7 +49,8 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
||||
if (newPercentile >= nextPercentile) {
|
||||
double currentPercentile = lastPercentile + stepSize;
|
||||
while (currentPercentile <= newPercentile) {
|
||||
percentiles.put(currentPercentile, duration);
|
||||
final String percentile = String.format(Locale.US, "%.3f", currentPercentile);
|
||||
percentiles.put(percentile, duration);
|
||||
currentPercentile += stepSize;
|
||||
}
|
||||
nextPercentile = currentPercentile;
|
||||
@@ -61,10 +62,15 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
public LinkedHashMap<Double, Long> getPercentiles() {
|
||||
public Percentiles getPercentiles() {
|
||||
return percentiles;
|
||||
}
|
||||
|
||||
public void collect(final LongLongHashMap map) {
|
||||
map.forEachOrdered(this);
|
||||
percentiles.put("100.000", maxValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// the rather large initial capacity should prevent too many grow&re-hash phases
|
||||
@@ -84,14 +90,27 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
||||
totalValues++;
|
||||
}
|
||||
|
||||
public Percentiles getPercentiles() {
|
||||
final long start = System.nanoTime();
|
||||
|
||||
final ToPercentiles toPercentiles = new ToPercentiles(totalValues);
|
||||
toPercentiles.collect(map);
|
||||
|
||||
final Percentiles result = toPercentiles.getPercentiles();
|
||||
System.out.println("getPercentiles took: " + (System.nanoTime() - start) / 1_000_000.0 + " ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregatedData getAggregatedData() {
|
||||
try {
|
||||
final char separator = ',';
|
||||
final char newline = '\n';
|
||||
|
||||
final long start = System.nanoTime();
|
||||
final ToPercentiles toPercentiles = new ToPercentiles(totalValues);
|
||||
map.forEachOrdered(toPercentiles);
|
||||
toPercentiles.collect(map);
|
||||
System.out.println("getAggregated took: " + (System.nanoTime() - start) / 1_000_000.0 + " ms");
|
||||
|
||||
final File dataFile = File.createTempFile("data", ".dat", tmpDir.toFile());
|
||||
try (final Writer output = new BufferedWriter(
|
||||
@@ -107,12 +126,6 @@ public class CumulativeDistributionCustomAggregator implements CustomAggregator
|
||||
data.append(value);
|
||||
data.append(newline);
|
||||
});
|
||||
|
||||
final long maxValue = toPercentiles.getMaxValue();
|
||||
data.append(100);
|
||||
data.append(separator);
|
||||
data.append(maxValue);
|
||||
data.append(newline);
|
||||
}
|
||||
output.write(data.toString());
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.lucares.pdb.plot.api;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Maps percentiles to their value. E.g.
|
||||
*
|
||||
* <pre>
|
||||
* {"50.00": 123, "75.00": 567}
|
||||
* </pre>
|
||||
*
|
||||
* This class uses Strings for the precentiles instead of doubles, because
|
||||
* doubles are bad keys for maps.
|
||||
*/
|
||||
public class Percentiles extends LinkedHashMap<String, Long> {
|
||||
|
||||
private static final long serialVersionUID = 4957667781086113971L;
|
||||
|
||||
public Percentiles() {
|
||||
super(0);
|
||||
}
|
||||
|
||||
public Percentiles(final int initialSize) {
|
||||
super(initialSize);
|
||||
}
|
||||
|
||||
public Percentiles(final Map<String, Long> percentiles) {
|
||||
super(percentiles.size());
|
||||
putAll(percentiles);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
import org.lucares.pdb.plot.api.AggregatorCollection;
|
||||
import org.lucares.pdb.plot.api.Limit;
|
||||
import org.lucares.pdb.plot.api.Percentiles;
|
||||
|
||||
public interface DataSeries {
|
||||
public static final Comparator<? super DataSeries> BY_NUMBER_OF_VALUES = (a, b) -> {
|
||||
@@ -35,6 +36,8 @@ public interface DataSeries {
|
||||
|
||||
public double getAverage();
|
||||
|
||||
public Percentiles getPercentiles();
|
||||
|
||||
public void setStyle(LineStyle style);
|
||||
|
||||
public LineStyle getStyle();
|
||||
@@ -114,5 +117,4 @@ public interface DataSeries {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.lucares.recommind.logs;
|
||||
|
||||
import org.lucares.pdb.plot.api.AggregatorCollection;
|
||||
import org.lucares.pdb.plot.api.CumulativeDistributionCustomAggregator;
|
||||
import org.lucares.pdb.plot.api.Percentiles;
|
||||
|
||||
public class FileBackedDataSeries implements DataSeries {
|
||||
|
||||
@@ -55,11 +57,19 @@ public class FileBackedDataSeries implements DataSeries {
|
||||
|
||||
@Override
|
||||
public double getAverage() {
|
||||
return csvSummary.getStatsAverage();
|
||||
return Math.round(csvSummary.getStatsAverage() * 10.0) / 10.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregatorCollection getAggregators() {
|
||||
return csvSummary.getAggregators();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Percentiles getPercentiles() {
|
||||
return csvSummary.getAggregators()//
|
||||
.getAggregator(CumulativeDistributionCustomAggregator.class)//
|
||||
.map(CumulativeDistributionCustomAggregator::getPercentiles)//
|
||||
.orElse(new Percentiles());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user