package org.apache.cassandra.stress.report; /* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.HdrHistogram.Histogram; // represents measurements taken over an interval of time // used for both single timer results and merged timer results public final class TimingInterval { private final Histogram responseTime = new Histogram(3); private final Histogram serviceTime = new Histogram(3); private final Histogram waitTime = new Histogram(3); public static final long[] EMPTY_SAMPLE = new long[0]; // nanos private long startNs = Long.MAX_VALUE; private long endNs = Long.MIN_VALUE; // discrete public long partitionCount; public long rowCount; public long errorCount; public final boolean isFixed; public TimingInterval(boolean isFixed){ this.isFixed = isFixed; } public String toString() { return String.format("Start: %d end: %d maxLatency: %d pCount: %d rcount: %d opCount: %d errors: %d", startNs, endNs, getLatencyHistogram().getMaxValue(), partitionCount, rowCount, getLatencyHistogram().getTotalCount(), errorCount); } public double opRate() { return getLatencyHistogram().getTotalCount() / ((endNs - startNs) * 0.000000001d); } public double adjustedRowRate() { return rowCount / ((endNs - (startNs + getLatencyHistogram().getMaxValue())) * 0.000000001d); } public double partitionRate() { return partitionCount / ((endNs - startNs) * 0.000000001d); } public double rowRate() { return rowCount / ((endNs - startNs) * 0.000000001d); } public double meanLatencyMs() { return getLatencyHistogram().getMean() * 0.000001d; } public double maxLatencyMs() { return getLatencyHistogram().getMaxValue() * 0.000001d; } public double medianLatencyMs() { return getLatencyHistogram().getValueAtPercentile(50.0) * 0.000001d; } /** * @param percentile between 0.0 and 100.0 * @return latency in milliseconds at percentile */ public double latencyAtPercentileMs(double percentile) { return getLatencyHistogram().getValueAtPercentile(percentile) * 0.000001d; } public long runTimeMs() { return (endNs - startNs) / 1000000; } public long endNanos() { return endNs; } public long startNanos() { return startNs; } public Histogram responseTime() { return responseTime; } public Histogram serviceTime() { return serviceTime; } public Histogram waitTime() { return waitTime; } private Histogram getLatencyHistogram() { if (!isFixed || responseTime.getTotalCount() == 0) return serviceTime; else return responseTime; } public static enum TimingParameter { OPRATE, ROWRATE, ADJROWRATE, PARTITIONRATE, MEANLATENCY, MAXLATENCY, MEDIANLATENCY, RANKLATENCY, ERRORCOUNT, PARTITIONCOUNT } String getStringValue(TimingParameter value) { return getStringValue(value, Float.NaN); } String getStringValue(TimingParameter value, double rank) { switch (value) { case OPRATE: return String.format("%,.0f", opRate()); case ROWRATE: return String.format("%,.0f", rowRate()); case ADJROWRATE: return String.format("%,.0f", adjustedRowRate()); case PARTITIONRATE: return String.format("%,.0f", partitionRate()); case MEANLATENCY: return String.format("%,.1f", meanLatencyMs()); case MAXLATENCY: return String.format("%,.1f", maxLatencyMs()); case MEDIANLATENCY: return String.format("%,.1f", medianLatencyMs()); case RANKLATENCY: return String.format("%,.1f", latencyAtPercentileMs(rank)); case ERRORCOUNT: return String.format("%,d", errorCount); case PARTITIONCOUNT: return String.format("%,d", partitionCount); default: throw new IllegalStateException(); } } public long operationCount() { return getLatencyHistogram().getTotalCount(); } public void startNanos(long started) { this.startNs = started; } public void endNanos(long ended) { this.endNs = ended; } public void reset() { this.endNs = Long.MIN_VALUE; this.startNs = Long.MAX_VALUE; this.errorCount = 0; this.rowCount = 0; this.partitionCount = 0; if(this.responseTime.getTotalCount() != 0) { this.responseTime.reset(); } if(this.serviceTime.getTotalCount() != 0) { this.serviceTime.reset(); } if(this.waitTime.getTotalCount() != 0) { this.waitTime.reset(); } } public void add(TimingInterval value) { if(this.startNs > value.startNs) { this.startNs = value.startNs; } if(this.endNs < value.endNs) { this.endNs = value.endNs; } this.errorCount += value.errorCount; this.rowCount += value.rowCount; this.partitionCount += value.partitionCount; if (value.responseTime.getTotalCount() != 0) { this.responseTime.add(value.responseTime); } if (value.serviceTime.getTotalCount() != 0) { this.serviceTime.add(value.serviceTime); } if (value.waitTime.getTotalCount() != 0) { this.waitTime.add(value.waitTime); } } }