cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject [1/2] cassandra git commit: Fix Cassandra Stress reporting thread model and precision
Date Wed, 07 Sep 2016 14:15:56 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 1d7466425 -> e73633cd8


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/report/Timer.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/report/Timer.java b/tools/stress/src/org/apache/cassandra/stress/report/Timer.java
new file mode 100644
index 0000000..b3df52f
--- /dev/null
+++ b/tools/stress/src/org/apache/cassandra/stress/report/Timer.java
@@ -0,0 +1,63 @@
+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.apache.cassandra.stress.StressAction.MeasurementSink;
+
+// a timer - this timer must be used by a single thread, and co-ordinates with other timers
by
+public final class Timer
+{
+    private final String opType;
+    private final MeasurementSink sink;
+
+    // event timing info
+    private long intendedTimeNs;
+    private long startTimeNs;
+
+    public Timer(String opType, MeasurementSink sink)
+    {
+        this.opType = opType;
+        this.sink = sink;
+    }
+
+
+    public void stop(long partitionCount, long rowCount, boolean error)
+    {
+        sink.record(opType, intendedTimeNs, startTimeNs, System.nanoTime(), rowCount, partitionCount,
error);
+        resetTimes();
+    }
+
+    private void resetTimes()
+    {
+        intendedTimeNs = startTimeNs = 0;
+    }
+
+    public void intendedTimeNs(long v)
+    {
+        intendedTimeNs = v;
+    }
+
+    public void start()
+    {
+        startTimeNs = System.nanoTime();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/report/TimingInterval.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/report/TimingInterval.java b/tools/stress/src/org/apache/cassandra/stress/report/TimingInterval.java
new file mode 100644
index 0000000..4d124a2
--- /dev/null
+++ b/tools/stress/src/org/apache/cassandra/stress/report/TimingInterval.java
@@ -0,0 +1,234 @@
+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);
+        }
+    }
+ }
+

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/report/TimingIntervals.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/report/TimingIntervals.java b/tools/stress/src/org/apache/cassandra/stress/report/TimingIntervals.java
new file mode 100644
index 0000000..747a42a
--- /dev/null
+++ b/tools/stress/src/org/apache/cassandra/stress/report/TimingIntervals.java
@@ -0,0 +1,128 @@
+package org.apache.cassandra.stress.report;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class TimingIntervals
+{
+    final Map<String, TimingInterval> intervals;
+
+    public TimingIntervals(Map<String, TimingInterval> intervals)
+    {
+        this.intervals = intervals;
+    }
+
+    public TimingInterval get(String opType)
+    {
+        return intervals.get(opType);
+    }
+
+
+    public String str(TimingInterval.TimingParameter value, String unit)
+    {
+        return str(value, Double.NaN, unit);
+    }
+
+    public String str(TimingInterval.TimingParameter value, double rank, String unit)
+    {
+        if (intervals.size() == 0)
+        {
+            return "[]";
+        }
+
+        StringBuilder sb = new StringBuilder("[");
+
+        for (Map.Entry<String, TimingInterval> entry : intervals.entrySet())
+        {
+            sb.append(entry.getKey());
+            sb.append(": ");
+            sb.append(entry.getValue().getStringValue(value, rank));
+            if (unit.length() > 0)
+            {
+                sb.append(" ");
+                sb.append(unit);
+            }
+            sb.append(", ");
+        }
+
+        sb.setLength(sb.length()-2);
+        sb.append("]");
+
+        return sb.toString();
+    }
+
+    public String opRates()
+    {
+        return str(TimingInterval.TimingParameter.OPRATE, "op/s");
+    }
+
+    public String partitionRates()
+    {
+        return str(TimingInterval.TimingParameter.PARTITIONRATE, "pk/s");
+    }
+
+    public String rowRates()
+    {
+        return str(TimingInterval.TimingParameter.ROWRATE, "row/s");
+    }
+
+    public String meanLatencies()
+    {
+        return str(TimingInterval.TimingParameter.MEANLATENCY, "ms");
+    }
+
+    public String maxLatencies()
+    {
+        return str(TimingInterval.TimingParameter.MAXLATENCY, "ms");
+    }
+
+    public String medianLatencies()
+    {
+        return str(TimingInterval.TimingParameter.MEDIANLATENCY, "ms");
+    }
+
+    public String latenciesAtPercentile(double rank)
+    {
+        return str(TimingInterval.TimingParameter.RANKLATENCY, rank, "ms");
+    }
+
+    public String errorCounts()
+    {
+        return str(TimingInterval.TimingParameter.ERRORCOUNT, "");
+    }
+
+    public String partitionCounts()
+    {
+        return str(TimingInterval.TimingParameter.PARTITIONCOUNT, "");
+    }
+
+    public long opRate()
+    {
+        long v = 0;
+        for (TimingInterval interval : intervals.values())
+            v += interval.opRate();
+        return v;
+    }
+
+    public long startNanos()
+    {
+        long start = Long.MAX_VALUE;
+        for (TimingInterval interval : intervals.values())
+            start = Math.min(start, interval.startNanos());
+        return start;
+    }
+
+    public long endNanos()
+    {
+        long end = Long.MIN_VALUE;
+        for (TimingInterval interval : intervals.values())
+            end = Math.max(end, interval.startNanos());
+        return end;
+    }
+
+    public Map<String, TimingInterval> intervals()
+    {
+        return intervals;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java
b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java
index c425719..b7f87e9 100644
--- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java
+++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefined.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.cassandra.stress.StressAction.MeasurementSink;
 import org.apache.cassandra.stress.generate.DistributionFactory;
 import org.apache.cassandra.stress.generate.PartitionGenerator;
 import org.apache.cassandra.stress.generate.SeedManager;
@@ -37,8 +38,8 @@ import org.apache.cassandra.stress.operations.FixedOpDistribution;
 import org.apache.cassandra.stress.operations.OpDistribution;
 import org.apache.cassandra.stress.operations.OpDistributionFactory;
 import org.apache.cassandra.stress.operations.predefined.PredefinedOperation;
+import org.apache.cassandra.stress.report.Timer;
 import org.apache.cassandra.stress.util.MultiPrintStream;
-import org.apache.cassandra.stress.util.Timing;
 
 // Settings unique to the mixed command type
 public class SettingsCommandPreDefined extends SettingsCommand
@@ -53,9 +54,11 @@ public class SettingsCommandPreDefined extends SettingsCommand
         final SeedManager seeds = new SeedManager(settings);
         return new OpDistributionFactory()
         {
-            public OpDistribution get(Timing timing, boolean isWarmup)
+            public OpDistribution get(boolean isWarmup, MeasurementSink sink)
             {
-                return new FixedOpDistribution(PredefinedOperation.operation(type, timing.newTimer(type.toString()),
+                final Timer timer1 = new Timer(type.toString(), sink);
+                final Timer timer = timer1;
+                return new FixedOpDistribution(PredefinedOperation.operation(type, timer,
                                                newGenerator(settings), seeds, settings, add));
             }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java
b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java
index 0e361ba..9c58c5b 100644
--- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java
+++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandPreDefinedMixed.java
@@ -30,8 +30,8 @@ import org.apache.cassandra.stress.generate.SeedManager;
 import org.apache.cassandra.stress.operations.OpDistributionFactory;
 import org.apache.cassandra.stress.operations.SampledOpDistributionFactory;
 import org.apache.cassandra.stress.operations.predefined.PredefinedOperation;
+import org.apache.cassandra.stress.report.Timer;
 import org.apache.cassandra.stress.util.MultiPrintStream;
-import org.apache.cassandra.stress.util.Timer;
 
 // Settings unique to the mixed command type
 public class SettingsCommandPreDefinedMixed extends SettingsCommandPreDefined

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java
b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java
index 7f30688..66e6df3 100644
--- a/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java
+++ b/tools/stress/src/org/apache/cassandra/stress/settings/SettingsCommandUser.java
@@ -36,8 +36,8 @@ import org.apache.cassandra.stress.generate.SeedManager;
 import org.apache.cassandra.stress.generate.TokenRangeIterator;
 import org.apache.cassandra.stress.operations.OpDistributionFactory;
 import org.apache.cassandra.stress.operations.SampledOpDistributionFactory;
+import org.apache.cassandra.stress.report.Timer;
 import org.apache.cassandra.stress.util.MultiPrintStream;
-import org.apache.cassandra.stress.util.Timer;
 
 // Settings unique to the mixed command type
 public class SettingsCommandUser extends SettingsCommand

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/util/Timer.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/util/Timer.java b/tools/stress/src/org/apache/cassandra/stress/util/Timer.java
deleted file mode 100644
index bb19bb6..0000000
--- a/tools/stress/src/org/apache/cassandra/stress/util/Timer.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package org.apache.cassandra.stress.util;
-/*
- *
- * 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 java.util.concurrent.CountDownLatch;
-
-import org.HdrHistogram.Histogram;
-
-// a timer - this timer must be used by a single thread, and co-ordinates with other timers
by
-public final class Timer
-{
-    private Histogram responseTime = new Histogram(3);
-    private Histogram serviceTime = new Histogram(3);
-    private Histogram waitTime = new Histogram(3);
-
-    // event timing info
-    private long intendedTimeNs;
-    private long startTimeNs;
-    private long endTimeNs;
-
-
-    // aggregate info
-    private long errorCount;
-    private long partitionCount;
-    private long rowCount;
-    private long max;
-    private long maxStart;
-    private long upToDateAsOf;
-    private long lastSnap = System.nanoTime();
-
-    // communication with summary/logging thread
-    private volatile CountDownLatch reportRequest;
-    volatile TimingInterval report;
-    private volatile TimingInterval finalReport;
-    private final boolean isFixed;
-
-    public Timer(boolean isFixed)
-    {
-        this.isFixed = isFixed;
-    }
-
-    public boolean running()
-    {
-        return finalReport == null;
-    }
-
-    public void stop(long partitionCount, long rowCount, boolean error)
-    {
-        endTimeNs = System.nanoTime();
-        maybeReport();
-        long now = System.nanoTime();
-        if (intendedTimeNs != 0)
-        {
-            long rTime = endTimeNs - intendedTimeNs;
-            responseTime.recordValue(rTime);
-            long wTime = startTimeNs - intendedTimeNs;
-            waitTime.recordValue(wTime);
-        }
-
-        long sTime = endTimeNs - startTimeNs;
-        serviceTime.recordValue(sTime);
-
-        if (sTime > max)
-        {
-            maxStart = startTimeNs;
-            max = sTime;
-        }
-        this.partitionCount += partitionCount;
-        this.rowCount += rowCount;
-        if (error)
-            this.errorCount++;
-        upToDateAsOf = now;
-        resetTimes();
-    }
-
-    private void resetTimes()
-    {
-        intendedTimeNs = startTimeNs = endTimeNs = 0;
-    }
-
-    private TimingInterval buildReport()
-    {
-        final TimingInterval report = new TimingInterval(lastSnap, upToDateAsOf, maxStart,
partitionCount,
-                rowCount, errorCount, responseTime, serviceTime, waitTime, isFixed);
-        // reset counters
-        partitionCount = 0;
-        rowCount = 0;
-        max = 0;
-        errorCount = 0;
-        lastSnap = upToDateAsOf;
-        responseTime = new Histogram(3);
-        serviceTime = new Histogram(3);
-        waitTime = new Histogram(3);
-
-        return report;
-    }
-
-    // checks to see if a report has been requested, and if so produces the report, signals
and clears the request
-    private void maybeReport()
-    {
-        if (reportRequest != null)
-        {
-            synchronized (this)
-            {
-                report = buildReport();
-                reportRequest.countDown();
-                reportRequest = null;
-            }
-        }
-    }
-
-    // checks to see if the timer is dead; if not requests a report, and otherwise fulfills
the request itself
-    synchronized void requestReport(CountDownLatch signal)
-    {
-        if (finalReport != null)
-        {
-            report = finalReport;
-            finalReport = new TimingInterval(0);
-            signal.countDown();
-        }
-        else
-            reportRequest = signal;
-    }
-
-    // closes the timer; if a request is outstanding, it furnishes the request, otherwise
it populates finalReport
-    public synchronized void close()
-    {
-        if (reportRequest == null)
-            finalReport = buildReport();
-        else
-        {
-            finalReport = new TimingInterval(0);
-            report = buildReport();
-            reportRequest.countDown();
-            reportRequest = null;
-        }
-    }
-
-    public void intendedTimeNs(long v)
-    {
-        intendedTimeNs = v;
-    }
-
-    public void start()
-    {
-        startTimeNs = System.nanoTime();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/util/Timing.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/util/Timing.java b/tools/stress/src/org/apache/cassandra/stress/util/Timing.java
deleted file mode 100644
index a304db7..0000000
--- a/tools/stress/src/org/apache/cassandra/stress/util/Timing.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package org.apache.cassandra.stress.util;
-/*
- *
- * 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 java.util.*;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-// relatively simple timing class for getting a uniform sample of latencies, and saving other
metrics
-// ensures accuracy of timing by having single threaded timers that are check-pointed by
the snapping thread,
-// which waits for them to report back. They report back the data up to the last event prior
to the check-point.
-// if the threads are blocked/paused this may mean a period of time longer than the checkpoint
elapses, but that all
-// metrics calculated over the interval are accurate
-public class Timing
-{
-    // concurrency: this should be ok as the consumers are created serially by StressAction.run
/ warmup
-    // Probably the CopyOnWriteArrayList could be changed to an ordinary list as well.
-    private final Map<String, List<Timer>> timers = new TreeMap<>();
-    private volatile TimingIntervals history;
-    private boolean done;
-    private boolean isFixed;
-
-    public Timing(boolean isFixed)
-    {
-        this.isFixed = isFixed;
-    }
-
-    // TIMING
-
-    public static class TimingResult<E>
-    {
-        public final E extra;
-        public final TimingIntervals intervals;
-        public TimingResult(E extra, TimingIntervals intervals)
-        {
-            this.extra = extra;
-            this.intervals = intervals;
-        }
-    }
-
-    public <E> TimingResult<E> snap(Callable<E> call) throws InterruptedException
-    {
-        // Count up total # of timers
-        int timerCount = 0;
-        for (List<Timer> timersForOperation : timers.values())
-        {
-            timerCount += timersForOperation.size();
-        }
-        final CountDownLatch ready = new CountDownLatch(timerCount);
-
-        // request reports
-        for (List <Timer> timersForOperation : timers.values())
-        {
-            for(Timer timer : timersForOperation)
-            {
-                timer.requestReport(ready);
-            }
-        }
-
-        E extra;
-        try
-        {
-            extra = call.call();
-        }
-        catch (Exception e)
-        {
-            if (e instanceof InterruptedException)
-                throw (InterruptedException) e;
-            throw new RuntimeException(e);
-        }
-
-        // TODO fail gracefully after timeout if a thread is stuck
-        if (!ready.await(5L, TimeUnit.MINUTES))
-        {
-            throw new RuntimeException("Timed out waiting for a timer thread - seems one
got stuck. Check GC/Heap size");
-        }
-
-        boolean done = true;
-
-        // reports have been filled in by timer threadCount, so merge
-        Map<String, TimingInterval> intervals = new TreeMap<>();
-        for (Map.Entry<String, List<Timer>> entry : timers.entrySet())
-        {
-            List<TimingInterval> operationIntervals = new ArrayList<>();
-            for (Timer timer : entry.getValue())
-            {
-                operationIntervals.add(timer.report);
-                done &= !timer.running();
-            }
-
-            intervals.put(entry.getKey(), TimingInterval.merge(operationIntervals,
-                                                              history.get(entry.getKey()).endNanos()));
-        }
-
-        TimingIntervals result = new TimingIntervals(intervals);
-        this.done = done;
-        history = history.merge(result, history.startNanos());
-        return new TimingResult<>(extra, result);
-    }
-
-    // build a new timer and add it to the set of running timers.
-    public Timer newTimer(String opType)
-    {
-        final Timer timer = new Timer(isFixed);
-
-        if (!timers.containsKey(opType))
-            timers.put(opType, new ArrayList<Timer>());
-
-        timers.get(opType).add(timer);
-        return timer;
-    }
-
-    public void start()
-    {
-        history = new TimingIntervals(timers.keySet());
-    }
-
-    public boolean done()
-    {
-        return done;
-    }
-
-    public TimingIntervals getHistory()
-    {
-        return history;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/util/TimingInterval.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/util/TimingInterval.java b/tools/stress/src/org/apache/cassandra/stress/util/TimingInterval.java
deleted file mode 100644
index bb9587f..0000000
--- a/tools/stress/src/org/apache/cassandra/stress/util/TimingInterval.java
+++ /dev/null
@@ -1,234 +0,0 @@
-package org.apache.cassandra.stress.util;
-/*
- *
- * 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;
-    private final Histogram serviceTime;
-    private final Histogram waitTime;
-
-    public static final long[] EMPTY_SAMPLE = new long[0];
-    // nanos
-    private final long startNs;
-    private final long endNs;
-    public final long pauseStart;
-
-    // discrete
-    public final long partitionCount;
-    public final long rowCount;
-    public final long errorCount;
-    public final boolean isFixed;
-
-
-    public String toString()
-    {
-        return String.format("Start: %d end: %d maxLatency: %d pauseStart: %d" +
-                             " pCount: %d rcount: %d opCount: %d errors: %d",
-                             startNs, endNs, getLatencyHistogram().getMaxValue(), pauseStart,
-                             partitionCount, rowCount, getLatencyHistogram().getTotalCount(),
errorCount);
-    }
-
-    TimingInterval(long time)
-    {
-        startNs = endNs = time;
-        partitionCount = rowCount = errorCount = 0;
-        pauseStart = 0;
-        responseTime = new Histogram(3);
-        serviceTime = new Histogram(3);
-        waitTime = new Histogram(3);
-        isFixed = false;
-    }
-
-    TimingInterval(long start, long end, long maxPauseStart, long partitionCount,
-                   long rowCount, long errorCount, Histogram r, Histogram s, Histogram w,
boolean isFixed)
-    {
-        this.startNs = start;
-        this.endNs = Math.max(end, start);
-        this.partitionCount = partitionCount;
-        this.rowCount = rowCount;
-        this.errorCount = errorCount;
-        this.pauseStart = maxPauseStart;
-        this.responseTime = r;
-        this.serviceTime = s;
-        this.waitTime = w;
-        this.isFixed = isFixed;
-
-    }
-
-    // merge multiple timer intervals together
-    static TimingInterval merge(Iterable<TimingInterval> intervals, long start)
-    {
-        long partitionCount = 0, rowCount = 0, errorCount = 0;
-        long end = 0;
-        long pauseStart = 0;
-        Histogram responseTime = new Histogram(3);
-        Histogram serviceTime = new Histogram(3);
-        Histogram waitTime = new Histogram(3);
-        boolean isFixed = false;
-        for (TimingInterval interval : intervals)
-        {
-            if (interval != null)
-            {
-                end = Math.max(end, interval.endNs);
-                partitionCount += interval.partitionCount;
-                rowCount += interval.rowCount;
-                errorCount += interval.errorCount;
-
-                if (interval.getLatencyHistogram().getMaxValue() > serviceTime.getMaxValue())
-                {
-                    pauseStart = interval.pauseStart;
-                }
-                responseTime.add(interval.responseTime);
-                serviceTime.add(interval.serviceTime);
-                waitTime.add(interval.waitTime);
-                isFixed |= interval.isFixed;
-            }
-        }
-
-
-        return new TimingInterval(start, end, pauseStart, partitionCount, rowCount,
-                                  errorCount, responseTime, serviceTime, waitTime, isFixed);
-
-    }
-
-    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();
-    }
- }
-

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e73633cd/tools/stress/src/org/apache/cassandra/stress/util/TimingIntervals.java
----------------------------------------------------------------------
diff --git a/tools/stress/src/org/apache/cassandra/stress/util/TimingIntervals.java b/tools/stress/src/org/apache/cassandra/stress/util/TimingIntervals.java
deleted file mode 100644
index 0586006..0000000
--- a/tools/stress/src/org/apache/cassandra/stress/util/TimingIntervals.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package org.apache.cassandra.stress.util;
-
-import java.util.Arrays;
-import java.util.Map;
-import java.util.TreeMap;
-
-public class TimingIntervals
-{
-    final Map<String, TimingInterval> intervals;
-    TimingIntervals(Iterable<String> opTypes)
-    {
-        long now = System.nanoTime();
-        intervals = new TreeMap<>();
-        for (String opType : opTypes)
-            intervals.put(opType, new TimingInterval(now));
-    }
-
-    TimingIntervals(Map<String, TimingInterval> intervals)
-    {
-        this.intervals = intervals;
-    }
-
-    public TimingIntervals merge(TimingIntervals with, long start)
-    {
-        assert intervals.size() == with.intervals.size();
-        TreeMap<String, TimingInterval> ret = new TreeMap<>();
-
-        for (String opType : intervals.keySet())
-        {
-            assert with.intervals.containsKey(opType);
-            ret.put(opType, TimingInterval.merge(Arrays.asList(intervals.get(opType), with.intervals.get(opType)),
start));
-        }
-
-        return new TimingIntervals(ret);
-    }
-
-    public TimingInterval get(String opType)
-    {
-        return intervals.get(opType);
-    }
-
-    public TimingInterval combine()
-    {
-        long start = Long.MAX_VALUE;
-        for (TimingInterval ti : intervals.values())
-            start = Math.min(start, ti.startNanos());
-
-        return TimingInterval.merge(intervals.values(), start);
-    }
-
-    public String str(TimingInterval.TimingParameter value, String unit)
-    {
-        return str(value, Double.NaN, unit);
-    }
-
-    public String str(TimingInterval.TimingParameter value, double rank, String unit)
-    {
-        StringBuilder sb = new StringBuilder("[");
-
-        for (Map.Entry<String, TimingInterval> entry : intervals.entrySet())
-        {
-            sb.append(entry.getKey());
-            sb.append(": ");
-            sb.append(entry.getValue().getStringValue(value, rank));
-            if (unit.length() > 0)
-            {
-                sb.append(" ");
-                sb.append(unit);
-            }
-            sb.append(", ");
-        }
-
-        sb.setLength(sb.length()-2);
-        sb.append("]");
-
-        return sb.toString();
-    }
-
-    public String opRates()
-    {
-        return str(TimingInterval.TimingParameter.OPRATE, "op/s");
-    }
-
-    public String partitionRates()
-    {
-        return str(TimingInterval.TimingParameter.PARTITIONRATE, "pk/s");
-    }
-
-    public String rowRates()
-    {
-        return str(TimingInterval.TimingParameter.ROWRATE, "row/s");
-    }
-
-    public String meanLatencies()
-    {
-        return str(TimingInterval.TimingParameter.MEANLATENCY, "ms");
-    }
-
-    public String maxLatencies()
-    {
-        return str(TimingInterval.TimingParameter.MAXLATENCY, "ms");
-    }
-
-    public String medianLatencies()
-    {
-        return str(TimingInterval.TimingParameter.MEDIANLATENCY, "ms");
-    }
-
-    public String latenciesAtPercentile(double rank)
-    {
-        return str(TimingInterval.TimingParameter.RANKLATENCY, rank, "ms");
-    }
-
-    public String errorCounts()
-    {
-        return str(TimingInterval.TimingParameter.ERRORCOUNT, "");
-    }
-
-    public String partitionCounts()
-    {
-        return str(TimingInterval.TimingParameter.PARTITIONCOUNT, "");
-    }
-
-    public long opRate()
-    {
-        long v = 0;
-        for (TimingInterval interval : intervals.values())
-            v += interval.opRate();
-        return v;
-    }
-
-    public long startNanos()
-    {
-        long start = Long.MAX_VALUE;
-        for (TimingInterval interval : intervals.values())
-            start = Math.min(start, interval.startNanos());
-        return start;
-    }
-
-    public long endNanos()
-    {
-        long end = Long.MIN_VALUE;
-        for (TimingInterval interval : intervals.values())
-            end = Math.max(end, interval.startNanos());
-        return end;
-    }
-
-    public Map<String, TimingInterval> intervals()
-    {
-        return intervals;
-    }
-}


Mime
View raw message