package com.epickrram.workshop.perf.app.processors; ////////////////////////////////////////////////////////////////////////////////// // Copyright 2015 Mark Price mark at epickrram.com // // // // 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. // ////////////////////////////////////////////////////////////////////////////////// import com.epickrram.workshop.perf.app.message.Packet; import com.epickrram.workshop.perf.config.CommandLineArgs; import com.epickrram.workshop.perf.support.NanoTimer; import org.HdrHistogram.Histogram; import org.HdrHistogram.HistogramLogWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; import static com.epickrram.workshop.perf.support.Histograms.HISTOGRAMS; public final class Accumulator { public static final String TRANSIT_TIME_HISTOGRAM_QUALIFIER = "transit-time"; public static final String INTER_MESSAGE_HISTOGRAM_QUALIFIER = "inter-message"; private final Histogram[] messageTransitTimeHistograms; private final Histogram[] interMessageTimeHistograms; private final NanoTimer nanoTimer; private final CommandLineArgs commandLineArgs; private int streamNumber = 0; private long previousMessageNanoTime; public Accumulator(final Histogram[] messageTransitTimeHistograms, final Histogram[] interMessageTimeHistograms, final NanoTimer nanoTimer, final CommandLineArgs commandLineArgs) { this.messageTransitTimeHistograms = messageTransitTimeHistograms; this.interMessageTimeHistograms = interMessageTimeHistograms; this.nanoTimer = nanoTimer; this.commandLineArgs = commandLineArgs; } public void process(final Packet packet) { final long nanoTime = nanoTimer.nanoTime(); if(packet.getSequenceInFile() != 0) { final long deltaNanos = nanoTime - packet.getReceivedNanoTime(); HISTOGRAMS.safeRecord(deltaNanos, messageTransitTimeHistograms[streamNumber]); HISTOGRAMS.safeRecord(nanoTime - previousMessageNanoTime, interMessageTimeHistograms[streamNumber]); } if(packet.isLastInFile()) { streamNumber++; } if(packet.isLastInStream()) { outputHistogram(mergeHistogramsAfterWarmupPeriod(messageTransitTimeHistograms), 0, TRANSIT_TIME_HISTOGRAM_QUALIFIER); outputHistogram(mergeHistogramsAfterWarmupPeriod(interMessageTimeHistograms), 0, INTER_MESSAGE_HISTOGRAM_QUALIFIER); } previousMessageNanoTime = nanoTime; } private Histogram mergeHistogramsAfterWarmupPeriod(final Histogram[] histograms) { final Histogram target = HISTOGRAMS.createHistogram(); for (int i = 0; i < histograms.length; i++) { if(i > commandLineArgs.getNumberOfWarmups()) { target.add(histograms[i]); } } return target; } private void outputHistogram(final Histogram histogram, final int streamNumber, final String qualifier) { try { try(final PrintStream printStream = new PrintStream(getHistogramOutputFile(commandLineArgs, streamNumber, qualifier))) { new HistogramLogWriter(printStream).outputIntervalHistogram(streamNumber, streamNumber + 1, histogram, 1d); } } catch (FileNotFoundException e) { throw new RuntimeException("Failed to write histogram", e); } } private static File getHistogramOutputFile(final CommandLineArgs commandLineArgs, final int streamNumber, final String qualifier) { return new File(commandLineArgs.getOutputDir(), "perf-workshop-" + "accumulator-histogram-" + qualifier + "-" + streamNumber + ".enc"); } }