* Issue #2288 - Cleanup the statistics classes. Cleaned up code, added Javadocs. Renamed SampleStatistics.set(long) to record(long). Signed-off-by: Simone Bordet <simone.bordet@gmail.com> * toString stddev Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
5712b0217f
commit
a3100e0211
|
@ -94,7 +94,7 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio
|
|||
_connections.decrement();
|
||||
|
||||
long elapsed = System.currentTimeMillis() - connection.getCreatedTimeStamp();
|
||||
_connectionsDuration.set(elapsed);
|
||||
_connectionsDuration.record(elapsed);
|
||||
|
||||
long bytesIn = connection.getBytesIn();
|
||||
if (bytesIn > 0)
|
||||
|
|
|
@ -80,10 +80,10 @@ public class ConnectorStatistics extends AbstractLifeCycle implements Dumpable,
|
|||
{
|
||||
long msgsIn=connection.getMessagesIn();
|
||||
long msgsOut=connection.getMessagesOut();
|
||||
_messagesIn.set(msgsIn);
|
||||
_messagesOut.set(msgsOut);
|
||||
_messagesIn.record(msgsIn);
|
||||
_messagesOut.record(msgsOut);
|
||||
_connectionStats.decrement();
|
||||
_connectionDurationStats.set(System.currentTimeMillis()-connection.getCreatedTimeStamp());
|
||||
_connectionDurationStats.record(System.currentTimeMillis()-connection.getCreatedTimeStamp());
|
||||
|
||||
Sample sample=_samples.remove(connection);
|
||||
if (sample!=null)
|
||||
|
|
|
@ -102,7 +102,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
|
|||
final long elapsed = System.currentTimeMillis()-request.getTimeStamp();
|
||||
|
||||
long d=_requestStats.decrement();
|
||||
_requestTimeStats.set(elapsed);
|
||||
_requestTimeStats.record(elapsed);
|
||||
|
||||
updateResponse(request);
|
||||
|
||||
|
@ -184,7 +184,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
|
|||
final long dispatched=now-start;
|
||||
|
||||
_dispatchedStats.decrement();
|
||||
_dispatchedTimeStats.set(dispatched);
|
||||
_dispatchedTimeStats.record(dispatched);
|
||||
|
||||
if (state.isSuspended())
|
||||
{
|
||||
|
@ -197,7 +197,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
|
|||
else if (state.isInitial())
|
||||
{
|
||||
long d=_requestStats.decrement();
|
||||
_requestTimeStats.set(dispatched);
|
||||
_requestTimeStats.record(dispatched);
|
||||
updateResponse(baseRequest);
|
||||
|
||||
// If we have no more dispatches, should we signal shutdown?
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import static java.lang.Math.round;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -63,9 +61,11 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||
import org.eclipse.jetty.util.statistic.SampleStatistic;
|
||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||
|
||||
import static java.lang.Math.round;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -1235,7 +1235,7 @@ public class SessionHandler extends ScopedHandler
|
|||
|
||||
if (session != null)
|
||||
{
|
||||
_sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
|
||||
_sessionTimeStats.record(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
|
||||
session.finishInvalidate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,51 +22,53 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
import java.util.concurrent.atomic.LongAccumulator;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Statistics on a counter value.
|
||||
* <p>
|
||||
* Keep total, current and maximum values of a counter that
|
||||
* can be incremented and decremented. The total refers only
|
||||
* to increments.
|
||||
*
|
||||
/**
|
||||
* <p>Statistics on a counter value.</p>
|
||||
* <p>This class keeps the total, current and maximum value of a counter
|
||||
* that can be incremented and decremented. The total refers only to increments.</p>
|
||||
*/
|
||||
public class CounterStatistic
|
||||
{
|
||||
protected final LongAccumulator _max = new LongAccumulator(Math::max,0L);
|
||||
protected final AtomicLong _current = new AtomicLong();
|
||||
protected final LongAdder _total = new LongAdder();
|
||||
private final LongAccumulator _max = new LongAccumulator(Math::max, 0L);
|
||||
private final AtomicLong _current = new AtomicLong();
|
||||
private final LongAdder _total = new LongAdder();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Resets the max and total to the current value.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
_total.reset();
|
||||
_max.reset();
|
||||
long current=_current.get();
|
||||
long current = _current.get();
|
||||
_total.add(current);
|
||||
_max.accumulate(current);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Resets the max, total and current value to the given parameter.
|
||||
*
|
||||
* @param value the new current value
|
||||
*/
|
||||
public void reset(final long value)
|
||||
{
|
||||
_current.set(value);
|
||||
_total.reset();
|
||||
_max.reset();
|
||||
if (value>0)
|
||||
if (value > 0)
|
||||
{
|
||||
_total.add(value);
|
||||
_max.accumulate(value);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param delta the amount to add to the count
|
||||
* @return the new value
|
||||
* @param delta the amount to add to the counter
|
||||
* @return the new counter value
|
||||
*/
|
||||
public long add(final long delta)
|
||||
{
|
||||
long value=_current.addAndGet(delta);
|
||||
long value = _current.addAndGet(delta);
|
||||
if (delta > 0)
|
||||
{
|
||||
_total.add(delta);
|
||||
|
@ -75,60 +77,56 @@ public class CounterStatistic
|
|||
return value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* increment the value by one
|
||||
* @return the new value, post increment
|
||||
* Increments the value by one.
|
||||
*
|
||||
* @return the new counter value after the increment
|
||||
*/
|
||||
public long increment()
|
||||
{
|
||||
long value=_current.incrementAndGet();
|
||||
long value = _current.incrementAndGet();
|
||||
_total.increment();
|
||||
_max.accumulate(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* decrement by 1
|
||||
* @return the new value, post-decrement
|
||||
* Decrements the value by one.
|
||||
*
|
||||
* @return the new counter value after the decrement
|
||||
*/
|
||||
public long decrement()
|
||||
{
|
||||
return _current.decrementAndGet();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return max value
|
||||
* @return max counter value
|
||||
*/
|
||||
public long getMax()
|
||||
{
|
||||
return _max.get();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return current value
|
||||
* @return current counter value
|
||||
*/
|
||||
public long getCurrent()
|
||||
{
|
||||
return _current.get();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return total value
|
||||
* @return total counter value
|
||||
*/
|
||||
public long getTotal()
|
||||
{
|
||||
return _total.sum();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{c=%d,m=%d,t=%d}",this.getClass().getSimpleName(),hashCode(),_current.get(),_max.get(),_total.sum());
|
||||
return String.format("%s@%x{c=%d,m=%d,t=%d}", getClass().getSimpleName(), hashCode(), getCurrent(), getMax(), getTotal());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,31 +22,26 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
import java.util.concurrent.atomic.LongAccumulator;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
import org.eclipse.jetty.util.Atomics;
|
||||
|
||||
|
||||
/**
|
||||
* SampledStatistics
|
||||
* <p>
|
||||
* Provides max, total, mean, count, variance, and standard deviation of continuous sequence of samples.
|
||||
* <p>
|
||||
* Calculates estimates of mean, variance, and standard deviation characteristics of a sample using a non synchronized
|
||||
* <p>Statistics on a sampled value.</p>
|
||||
* <p>Provides max, total, mean, count, variance, and standard deviation of continuous sequence of samples.</p>
|
||||
* <p>Calculates estimates of mean, variance, and standard deviation characteristics of a sample using a non synchronized
|
||||
* approximation of the on-line algorithm presented in <cite>Donald Knuth's Art of Computer Programming, Volume 2,
|
||||
* Semi numerical Algorithms, 3rd edition, page 232, Boston: Addison-Wesley</cite>. that cites a 1962 paper by B.P. Welford that
|
||||
* can be found by following <a href="http://www.jstor.org/pss/1266577">Note on a Method for Calculating Corrected Sums
|
||||
* of Squares and Products</a>
|
||||
* <p>
|
||||
* This algorithm is also described in Wikipedia at <a href=
|
||||
* "http://en.wikipedia.org/w/index.php?title=Algorithms_for_calculating_variance&section=4#On-line_algorithm">
|
||||
* Algorithms for calculating variance </a>
|
||||
* Semi numerical Algorithms, 3rd edition, page 232, Boston: Addison-Wesley</cite>. That cites a 1962 paper by B.P. Welford:
|
||||
* <a href="http://www.jstor.org/pss/1266577">Note on a Method for Calculating Corrected Sums of Squares and Products</a></p>
|
||||
* <p>This algorithm is also described in Wikipedia in the section "Online algorithm":
|
||||
* <a href="https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance">Algorithms for calculating variance</a>.</p>
|
||||
*/
|
||||
public class SampleStatistic
|
||||
{
|
||||
protected final LongAccumulator _max = new LongAccumulator(Math::max,0L);
|
||||
protected final AtomicLong _total = new AtomicLong();
|
||||
protected final AtomicLong _count = new AtomicLong();
|
||||
protected final LongAdder _totalVariance100 = new LongAdder();
|
||||
private final LongAccumulator _max = new LongAccumulator(Math::max, 0L);
|
||||
private final AtomicLong _total = new AtomicLong();
|
||||
private final AtomicLong _count = new AtomicLong();
|
||||
private final LongAdder _totalVariance100 = new LongAdder();
|
||||
|
||||
/**
|
||||
* Resets the statistics.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
_max.reset();
|
||||
|
@ -55,61 +50,89 @@ public class SampleStatistic
|
|||
_totalVariance100.reset();
|
||||
}
|
||||
|
||||
public void set(final long sample)
|
||||
/**
|
||||
* Records a sample value.
|
||||
*
|
||||
* @param sample the value to record.
|
||||
*/
|
||||
public void record(long sample)
|
||||
{
|
||||
long total = _total.addAndGet(sample);
|
||||
long count = _count.incrementAndGet();
|
||||
|
||||
if (count>1)
|
||||
if (count > 1)
|
||||
{
|
||||
long mean10 = total*10/count;
|
||||
long delta10 = sample*10 - mean10;
|
||||
_totalVariance100.add(delta10*delta10);
|
||||
long mean10 = total * 10 / count;
|
||||
long delta10 = sample * 10 - mean10;
|
||||
_totalVariance100.add(delta10 * delta10);
|
||||
}
|
||||
|
||||
_max.accumulate(sample);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the max value
|
||||
* @deprecated use {@link #record(long)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void set(long sample)
|
||||
{
|
||||
record(sample);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the max value of the recorded samples
|
||||
*/
|
||||
public long getMax()
|
||||
{
|
||||
return _max.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sum of all the recorded samples
|
||||
*/
|
||||
public long getTotal()
|
||||
{
|
||||
return _total.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of samples recorded
|
||||
*/
|
||||
public long getCount()
|
||||
{
|
||||
return _count.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the average value of the samples recorded, or zero if there are no samples
|
||||
*/
|
||||
public double getMean()
|
||||
{
|
||||
return (double)_total.get()/_count.get();
|
||||
long count = getCount();
|
||||
return count > 0 ? (double)_total.get() / _count.get() : 0.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the variance of the samples recorded, or zero if there are less than 2 samples
|
||||
*/
|
||||
public double getVariance()
|
||||
{
|
||||
final long variance100 = _totalVariance100.sum();
|
||||
final long count = _count.get();
|
||||
|
||||
return count>1?((double)variance100)/100.0/(count-1):0.0;
|
||||
long variance100 = _totalVariance100.sum();
|
||||
long count = getCount();
|
||||
return count > 1 ? variance100 / 100.0D / (count - 1) : 0.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the standard deviation of the samples recorded
|
||||
*/
|
||||
public double getStdDev()
|
||||
{
|
||||
return Math.sqrt(getVariance());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{c=%d,m=%d,t=%d,v100=%d}",this.getClass().getSimpleName(),hashCode(),_count.get(),_max.get(),_total.get(),_totalVariance100.sum());
|
||||
return String.format("%s@%x{count=%d,mean=%d,total=%d,stddev=%f}", getClass().getSimpleName(), hashCode(), getCount(), getMax(), getTotal(), getStdDev());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
package org.eclipse.jetty.util.statistic;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public class SampleStatisticTest
|
||||
|
@ -55,12 +55,13 @@ public class SampleStatisticTest
|
|||
{
|
||||
stats.reset();
|
||||
for (long x : data[d])
|
||||
stats.set(x);
|
||||
stats.record(x);
|
||||
|
||||
assertEquals("count"+d,data[d].length, (int)stats.getCount());
|
||||
assertNearEnough("mean"+d,results[d][0], stats.getMean());
|
||||
assertNearEnough("stddev"+d,results[d][1], stats.getStdDev());
|
||||
}
|
||||
System.err.println(stats);
|
||||
}
|
||||
|
||||
private void assertNearEnough(String test,double expected, double actual)
|
||||
|
|
Loading…
Reference in New Issue