Skip to content
Snippets Groups Projects
Commit 03e52fab authored by nitsanw's avatar nitsanw
Browse files

Refactor OneMeasurement: Make returncodes private final, make _name

final, refactor repeated export code from subclasses.
parent e01dd5e5
No related branches found
No related tags found
No related merge requests found
...@@ -29,8 +29,8 @@ import com.yahoo.ycsb.measurements.exporter.MeasurementsExporter; ...@@ -29,8 +29,8 @@ import com.yahoo.ycsb.measurements.exporter.MeasurementsExporter;
*/ */
public abstract class OneMeasurement { public abstract class OneMeasurement {
String _name; private final String _name;
final ConcurrentHashMap<Integer, AtomicInteger> returncodes; private final ConcurrentHashMap<Integer, AtomicInteger> _returncodes;
public String getName() { public String getName() {
return _name; return _name;
...@@ -41,7 +41,7 @@ public abstract class OneMeasurement { ...@@ -41,7 +41,7 @@ public abstract class OneMeasurement {
*/ */
public OneMeasurement(String _name) { public OneMeasurement(String _name) {
this._name = _name; this._name = _name;
this.returncodes = new ConcurrentHashMap<Integer, AtomicInteger>(); this._returncodes = new ConcurrentHashMap<Integer, AtomicInteger>();
} }
public abstract void measure(int latency); public abstract void measure(int latency);
...@@ -53,10 +53,10 @@ public abstract class OneMeasurement { ...@@ -53,10 +53,10 @@ public abstract class OneMeasurement {
*/ */
public void reportReturnCode(int code) { public void reportReturnCode(int code) {
Integer Icode = code; Integer Icode = code;
AtomicInteger counter = returncodes.get(Icode); AtomicInteger counter = _returncodes.get(Icode);
if (counter == null) { if (counter == null) {
AtomicInteger other = returncodes.putIfAbsent(Icode, counter = new AtomicInteger()); AtomicInteger other = _returncodes.putIfAbsent(Icode, counter = new AtomicInteger());
if (other != null) { if (other != null) {
counter = other; counter = other;
} }
...@@ -73,4 +73,9 @@ public abstract class OneMeasurement { ...@@ -73,4 +73,9 @@ public abstract class OneMeasurement {
*/ */
public abstract void exportMeasurements(MeasurementsExporter exporter) throws IOException; public abstract void exportMeasurements(MeasurementsExporter exporter) throws IOException;
protected final void exportReturnCodes(MeasurementsExporter exporter) throws IOException {
for (Map.Entry<Integer, AtomicInteger> entry : _returncodes.entrySet()) {
exporter.write(getName(), "Return=" + entry.getKey(), entry.getValue().get());
}
}
} }
...@@ -34,63 +34,63 @@ import org.HdrHistogram.Recorder; ...@@ -34,63 +34,63 @@ import org.HdrHistogram.Recorder;
import com.yahoo.ycsb.measurements.exporter.MeasurementsExporter; import com.yahoo.ycsb.measurements.exporter.MeasurementsExporter;
/** /**
* Take measurements and maintain a HdrHistogram of a given metric, such as * Take measurements and maintain a HdrHistogram of a given metric, such as READ
* READ LATENCY. * LATENCY.
* *
* @author nitsanw * @author nitsanw
* *
*/ */
public class OneMeasurementHdrHistogram extends OneMeasurement { public class OneMeasurementHdrHistogram extends OneMeasurement {
// we need one log per measurement histogram // we need one log per measurement histogram
final PrintStream log; final PrintStream log;
final HistogramLogWriter histogramLogWriter; final HistogramLogWriter histogramLogWriter;
final Recorder histogram = new Recorder(3); final Recorder histogram = new Recorder(3);
Histogram totalHistogram; Histogram totalHistogram;
public OneMeasurementHdrHistogram(String name, Properties props) { public OneMeasurementHdrHistogram(String name, Properties props) {
super(name); super(name);
boolean shouldLog = Boolean.parseBoolean(props.getProperty("hdrhistogram.fileoutput", "false")); boolean shouldLog = Boolean.parseBoolean(props.getProperty("hdrhistogram.fileoutput", "false"));
if (!shouldLog) { if (!shouldLog) {
log = null; log = null;
histogramLogWriter = null; histogramLogWriter = null;
return; return;
} }
try { try {
final String hdrOutputFilename = props.getProperty("hdrhistogram.output.path", "") +name+".hdr"; final String hdrOutputFilename = props.getProperty("hdrhistogram.output.path", "") + name + ".hdr";
log = new PrintStream(new FileOutputStream(hdrOutputFilename), false); log = new PrintStream(new FileOutputStream(hdrOutputFilename), false);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
throw new RuntimeException("Failed to open hdr histogram output file", e); throw new RuntimeException("Failed to open hdr histogram output file", e);
} }
histogramLogWriter = new HistogramLogWriter(log); histogramLogWriter = new HistogramLogWriter(log);
histogramLogWriter.outputComment("[Logging for: " + name + "]"); histogramLogWriter.outputComment("[Logging for: " + name + "]");
histogramLogWriter.outputLogFormatVersion(); histogramLogWriter.outputLogFormatVersion();
histogramLogWriter.outputStartTime(System.currentTimeMillis()); histogramLogWriter.outputStartTime(System.currentTimeMillis());
histogramLogWriter.outputLegend(); histogramLogWriter.outputLegend();
} }
/** /**
* It appears latency is reported in micros. * It appears latency is reported in micros. Using {@link Recorder} to
* Using {@link Recorder} to support concurrent updates to histogram. * support concurrent updates to histogram.
* *
* @see com.yahoo.ycsb.OneMeasurement#measure(int) * @see com.yahoo.ycsb.OneMeasurement#measure(int)
*/ */
public void measure(int latencyInMicros) { public void measure(int latencyInMicros) {
histogram.recordValue(latencyInMicros); histogram.recordValue(latencyInMicros);
} }
/** /**
* This is called from a main thread, on orderly termination. * This is called from a main thread, on orderly termination.
* *
* @see com.yahoo.ycsb.measurements.OneMeasurement#exportMeasurements(com.yahoo.ycsb.measurements.exporter.MeasurementsExporter) * @see com.yahoo.ycsb.measurements.OneMeasurement#exportMeasurements(com.yahoo.ycsb.measurements.exporter.MeasurementsExporter)
*/ */
@Override @Override
public void exportMeasurements(MeasurementsExporter exporter) throws IOException { public void exportMeasurements(MeasurementsExporter exporter) throws IOException {
// accumulate the last interval which was not caught by status thread // accumulate the last interval which was not caught by status thread
Histogram intervalHistogram = getIntervalHistogramAndAccumulate(); Histogram intervalHistogram = getIntervalHistogramAndAccumulate();
if(histogramLogWriter != null) { if (histogramLogWriter != null) {
histogramLogWriter.outputIntervalHistogram(intervalHistogram); histogramLogWriter.outputIntervalHistogram(intervalHistogram);
// we can close now // we can close now
log.close(); log.close();
...@@ -101,47 +101,43 @@ public class OneMeasurementHdrHistogram extends OneMeasurement { ...@@ -101,47 +101,43 @@ public class OneMeasurementHdrHistogram extends OneMeasurement {
exporter.write(getName(), "MaxLatency(us)", totalHistogram.getMaxValue()); exporter.write(getName(), "MaxLatency(us)", totalHistogram.getMaxValue());
exporter.write(getName(), "95thPercentileLatency(ms)", totalHistogram.getValueAtPercentile(90)/1000); exporter.write(getName(), "95thPercentileLatency(ms)", totalHistogram.getValueAtPercentile(90)/1000);
exporter.write(getName(), "99thPercentileLatency(ms)", totalHistogram.getValueAtPercentile(99)/1000); exporter.write(getName(), "99thPercentileLatency(ms)", totalHistogram.getValueAtPercentile(99)/1000);
for (Map.Entry<Integer, AtomicInteger> entry : returncodes.entrySet()) { exportReturnCodes(exporter);
exporter.write(getName(), "Return=" + entry.getKey(), entry.getValue().get());
}
} }
/** /**
* This is called periodically from the StatusThread. There's a single StatusThread per Client process. * This is called periodically from the StatusThread. There's a single
* We optionally serialize the interval to log on this opportunity. * StatusThread per Client process. We optionally serialize the interval to
* @see com.yahoo.ycsb.measurements.OneMeasurement#getSummary() * log on this opportunity.
*/ *
@Override * @see com.yahoo.ycsb.measurements.OneMeasurement#getSummary()
public String getSummary() { */
Histogram intervalHistogram = getIntervalHistogramAndAccumulate(); @Override
// we use the summary interval as the histogram file interval. public String getSummary() {
if(histogramLogWriter != null) { Histogram intervalHistogram = getIntervalHistogramAndAccumulate();
histogramLogWriter.outputIntervalHistogram(intervalHistogram); // we use the summary interval as the histogram file interval.
} if (histogramLogWriter != null) {
histogramLogWriter.outputIntervalHistogram(intervalHistogram);
DecimalFormat d = new DecimalFormat("#.##"); }
return "[" + getName() +
": Count=" + intervalHistogram.getTotalCount() + DecimalFormat d = new DecimalFormat("#.##");
", Max=" + intervalHistogram.getMaxValue() + return "[" + getName() + ": Count=" + intervalHistogram.getTotalCount() + ", Max="
", Min=" + intervalHistogram.getMinValue() + + intervalHistogram.getMaxValue() + ", Min=" + intervalHistogram.getMinValue() + ", Avg="
", Avg=" + d.format(intervalHistogram.getMean()) + + d.format(intervalHistogram.getMean()) + ", 90=" + d.format(intervalHistogram.getValueAtPercentile(90))
", 90=" + d.format(intervalHistogram.getValueAtPercentile(90)) + + ", 99=" + d.format(intervalHistogram.getValueAtPercentile(99)) + ", 99.9="
", 99=" + d.format(intervalHistogram.getValueAtPercentile(99)) + + d.format(intervalHistogram.getValueAtPercentile(99.9)) + ", 99.99="
", 99.9=" + d.format(intervalHistogram.getValueAtPercentile(99.9)) + + d.format(intervalHistogram.getValueAtPercentile(99.99)) + "]";
", 99.99=" + d.format(intervalHistogram.getValueAtPercentile(99.99)) +"]"; }
}
private Histogram getIntervalHistogramAndAccumulate() {
private Histogram getIntervalHistogramAndAccumulate() { Histogram intervalHistogram = histogram.getIntervalHistogram();
Histogram intervalHistogram = histogram.getIntervalHistogram(); // add this to the total time histogram.
// add this to the total time histogram. if (totalHistogram == null) {
if (totalHistogram == null) { totalHistogram = intervalHistogram;
totalHistogram = intervalHistogram; } else {
} totalHistogram.add(intervalHistogram);
else { }
totalHistogram.add(intervalHistogram); return intervalHistogram;
} }
return intervalHistogram;
}
} }
...@@ -119,9 +119,7 @@ public class OneMeasurementHistogram extends OneMeasurement ...@@ -119,9 +119,7 @@ public class OneMeasurementHistogram extends OneMeasurement
} }
} }
for (Map.Entry<Integer, AtomicInteger> entry : returncodes.entrySet()) { exportReturnCodes(exporter);
exporter.write(getName(), "Return=" + entry.getKey(), entry.getValue().get());
}
for (int i=0; i<_buckets; i++) for (int i=0; i<_buckets; i++)
{ {
......
...@@ -125,24 +125,18 @@ public class OneMeasurementTimeSeries extends OneMeasurement ...@@ -125,24 +125,18 @@ public class OneMeasurementTimeSeries extends OneMeasurement
@Override @Override
public void exportMeasurements(MeasurementsExporter exporter) throws IOException public void exportMeasurements(MeasurementsExporter exporter) throws IOException {
{
checkEndOfUnit(true); checkEndOfUnit(true);
exporter.write(getName(), "Operations", operations); exporter.write(getName(), "Operations", operations);
exporter.write(getName(), "AverageLatency(us)", (((double)totallatency)/((double)operations))); exporter.write(getName(), "AverageLatency(us)", (((double) totallatency) / ((double) operations)));
exporter.write(getName(), "MinLatency(us)", min); exporter.write(getName(), "MinLatency(us)", min);
exporter.write(getName(), "MaxLatency(us)", max); exporter.write(getName(), "MaxLatency(us)", max);
//TODO: 95th and 99th percentile latency // TODO: 95th and 99th percentile latency
for (Map.Entry<Integer, AtomicInteger> entry : returncodes.entrySet()) { exportReturnCodes(exporter);
exporter.write(getName(), "Return=" + entry.getKey(), entry.getValue().get()); for (SeriesUnit unit : _measurements) {
}
for (SeriesUnit unit : _measurements)
{
exporter.write(getName(), Long.toString(unit.time), unit.average); exporter.write(getName(), Long.toString(unit.time), unit.average);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment