You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2016/10/14 14:36:25 UTC
svn commit: r1764918 - in /qpid/java/trunk/broker-core/src:
main/java/org/apache/qpid/server/stats/StatisticsCounter.java
test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
Author: rgodfrey
Date: Fri Oct 14 14:36:25 2016
New Revision: 1764918
URL: http://svn.apache.org/viewvc?rev=1764918&view=rev
Log:
QPID-7447 : Remove synchronization on StatisticsCounter
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java?rev=1764918&r1=1764917&r2=1764918&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java Fri Oct 14 14:36:25 2016
@@ -18,12 +18,12 @@
*/
package org.apache.qpid.server.stats;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicLong;
-
/**
* This class collects statistics and counts the total, rate per second and
* peak rate per second values for the events that are registered with it.
@@ -36,15 +36,7 @@ public class StatisticsCounter
private static final String COUNTER = "counter";
private static final AtomicLong _counterIds = new AtomicLong(0L);
-
- private long _peak = 0L;
- private long _total = 0L;
- private long _temp = 0L;
- private long _last = 0L;
- private long _rate = 0L;
- private long _start;
-
private final long _period;
private final String _name;
@@ -63,10 +55,91 @@ public class StatisticsCounter
_period = period;
_name = name + "-" + + _counterIds.incrementAndGet();
- _start = System.currentTimeMillis();
- _last = _start / _period;
+ _currentSample.set(new Sample(period));
}
-
+
+ private static final class Sample
+ {
+ private final long _sampleId;
+ private final AtomicLong _count = new AtomicLong();
+ private final AtomicLong _total;
+ private final long _peak;
+ private final long _lastRate;
+ private final long _start;
+ private final long _period;
+
+ private Sample(final long period)
+ {
+ _period = period;
+ _total = new AtomicLong();
+ _peak = 0L;
+ _lastRate = 0L;
+ _start = System.currentTimeMillis();
+ _sampleId = _start / period;
+
+ }
+
+ private Sample(final long timestamp, Sample priorSample)
+ {
+ _period = priorSample._period;
+ _sampleId = timestamp / _period;
+ _total = priorSample._total;
+ _peak = priorSample.getRate() > priorSample.getPeak() ? priorSample.getRate() : priorSample.getPeak();
+ _lastRate = priorSample.getRate();
+ _start = priorSample._start;
+ }
+
+ public long getTotal()
+ {
+ return _total.get();
+ }
+
+ public long getRate()
+ {
+ return _count.get();
+ }
+
+ public long getPeak()
+ {
+ return _peak;
+ }
+
+ public long getLastRate()
+ {
+ return _lastRate;
+ }
+
+ public long getStart()
+ {
+ return _start;
+ }
+
+ public boolean add(final long value, final long timestamp)
+ {
+ if(timestamp >= _start)
+ {
+ long eventSampleId = timestamp / _period;
+ if(eventSampleId > _sampleId)
+ {
+ return false;
+ }
+ _total.addAndGet(value);
+ if(eventSampleId == _sampleId)
+ {
+ _count.addAndGet(value);
+ }
+ return true;
+ }
+ else
+ {
+ // ignore - event occurred before reset;
+ return true;
+ }
+ }
+ }
+
+ private AtomicReference<Sample> _currentSample = new AtomicReference<>();
+
public void registerEvent(long value)
{
@@ -75,22 +148,12 @@ public class StatisticsCounter
public void registerEvent(long value, long timestamp)
{
- long thisSample = (timestamp / _period);
- synchronized (this)
+ Sample currentSample;
+
+ while(!(currentSample = getSample()).add(value, timestamp))
{
- if (thisSample > _last)
- {
- _last = thisSample;
- _rate = _temp;
- _temp = 0L;
- if (_rate > _peak)
- {
- _peak = _rate;
- }
- }
-
- _total += value;
- _temp += value;
+ Sample nextSample = new Sample(timestamp, currentSample);
+ _currentSample.compareAndSet(currentSample, nextSample);
}
}
@@ -109,40 +172,37 @@ public class StatisticsCounter
public void reset()
{
_log.info("Resetting statistics for counter: " + _name);
- _peak = 0L;
- _rate = 0L;
- _total = 0L;
- _start = System.currentTimeMillis();
- _last = _start / _period;
+
+ _currentSample.set(new Sample(_period));
}
public double getPeak()
{
update();
- return (double) _peak / ((double) _period / 1000.0d);
+ return (double) getSample().getPeak() / ((double) _period / 1000.0d);
+ }
+
+ private Sample getSample()
+ {
+ return _currentSample.get();
}
public double getRate()
{
update();
- return (double) _rate / ((double) _period / 1000.0d);
+ return (double) getSample().getLastRate() / ((double) _period / 1000.0d);
}
public long getTotal()
{
- return _total;
+ return getSample().getTotal();
}
public long getStart()
{
- return _start;
+ return getSample().getStart();
}
- public Date getStartTime()
- {
- return new Date(_start);
- }
-
public String getName()
{
return _name;
Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java?rev=1764918&r1=1764917&r2=1764918&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java Fri Oct 14 14:36:25 2016
@@ -92,39 +92,6 @@ public class StatisticsCounterTest exten
Thread.sleep(1000);
assertEquals(2000.0, counter.getPeak());
}
-
- /**
- * Test that peak rate is reported correctly for out-of-order messages,
- * and the total is also unaffected.
- */
- public void testPeakOutOfOrder() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(1000, start + 2500);
- Thread.sleep(1500);
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(2000, start + 1500);
-
- // make sure, that getPeak invocation occurs at "start + 2500"
- // if test thread over-sleeps for 500+ mls
- // the peak value can be incremented and test will fail
- long sleep = start + 2500 - System.currentTimeMillis();
- Thread.sleep(sleep < 0 ? 0 : sleep);
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(1000, start + 500);
- Thread.sleep(1500);
- assertEquals(4000.0, counter.getPeak());
- Thread.sleep(2000);
- assertEquals(4000.0, counter.getPeak());
- counter.registerEvent(1000, start + 500);
- assertEquals(4000.0, counter.getPeak());
- Thread.sleep(2000);
- counter.registerEvent(1000);
- assertEquals(4000.0, counter.getPeak());
- assertEquals(6000, counter.getTotal());
- }
/**
* Test the current rate is generated correctly.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org