Author: markt
Date: Mon Mar 3 15:04:07 2014
New Revision: 1573581
URL: http://svn.apache.org/r1573581
Log:
Faster statistics collection.
Modified:
commons/proper/pool/trunk/src/changes/changes.xml
commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
Modified: commons/proper/pool/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/changes/changes.xml?rev=1573581&r1=1573580&r2=1573581&view=diff
==============================================================================
--- commons/proper/pool/trunk/src/changes/changes.xml (original)
+++ commons/proper/pool/trunk/src/changes/changes.xml Mon Mar 3 15:04:07 2014
@@ -45,6 +45,10 @@ The <action> type attribute can be add,u
<body>
<release version="2.3" date="TBD" description=
"TBD">
+ <action dev="markt" type="fix">
+ Improve performance of statistics collection for pools that extend
+ BaseGenericObjectPool.
+ </action>
</release>
<release version="2.2" date="2014-02-24" description=
"This is a maintenance release that adds a new testOnCreate configuration
option
Modified:
commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
URL:
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java?rev=1573581&r1=1573580&r2=1573581&view=diff
==============================================================================
---
commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
(original)
+++
commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2/impl/BaseGenericObjectPool.java
Mon Mar 3 15:04:07 2014
@@ -20,10 +20,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong;
@@ -110,9 +107,9 @@ public abstract class BaseGenericObjectP
final AtomicLong destroyedCount = new AtomicLong(0);
final AtomicLong destroyedByEvictorCount = new AtomicLong(0);
final AtomicLong destroyedByBorrowValidationCount = new AtomicLong(0);
- private final LinkedList<Long> activeTimes = new LinkedList<Long>(); //
@GuardedBy("activeTimes") - except in initStats()
- private final LinkedList<Long> idleTimes = new LinkedList<Long>(); //
@GuardedBy("activeTimes") - except in initStats()
- private final LinkedList<Long> waitTimes = new LinkedList<Long>(); //
@GuardedBy("activeTimes") - except in initStats()
+ private final StatsStore activeTimes = new
StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
+ private final StatsStore idleTimes = new
StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
+ private final StatsStore waitTimes = new
StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
private final Object maxBorrowWaitTimeMillisLock = new Object();
private volatile long maxBorrowWaitTimeMillis = 0; //
@GuardedBy("maxBorrowWaitTimeMillisLock")
private SwallowedExceptionListener swallowedExceptionListener = null;
@@ -140,9 +137,6 @@ public abstract class BaseGenericObjectP
// save the current CCL to be used later by the evictor Thread
factoryClassLoader = Thread.currentThread().getContextClassLoader();
-
- // Initialise the attributes used to record rolling averages
- initStats();
}
@@ -767,7 +761,7 @@ public abstract class BaseGenericObjectP
* recently returned objects
*/
public final long getMeanActiveTimeMillis() {
- return getMeanFromStatsCache(activeTimes);
+ return activeTimes.getMean();
}
/**
@@ -777,7 +771,7 @@ public abstract class BaseGenericObjectP
* borrowed objects
*/
public final long getMeanIdleTimeMillis() {
- return getMeanFromStatsCache(idleTimes);
+ return idleTimes.getMean();
}
/**
@@ -787,7 +781,7 @@ public abstract class BaseGenericObjectP
* to wait to borrow an object from the pool
*/
public final long getMeanBorrowWaitTimeMillis() {
- return getMeanFromStatsCache(waitTimes);
+ return waitTimes.getMean();
}
/**
@@ -857,14 +851,8 @@ public abstract class BaseGenericObjectP
*/
final void updateStatsBorrow(PooledObject<T> p, long waitTime) {
borrowedCount.incrementAndGet();
- synchronized (idleTimes) {
- idleTimes.add(Long.valueOf(p.getIdleTimeMillis()));
- idleTimes.poll();
- }
- synchronized (waitTimes) {
- waitTimes.add(Long.valueOf(waitTime));
- waitTimes.poll();
- }
+ idleTimes.add(p.getIdleTimeMillis());
+ waitTimes.add(waitTime);
synchronized (maxBorrowWaitTimeMillisLock) {
if (waitTime > maxBorrowWaitTimeMillis) {
maxBorrowWaitTimeMillis = waitTime;
@@ -879,10 +867,7 @@ public abstract class BaseGenericObjectP
*/
final void updateStatsReturn(long activeTime) {
returnedCount.incrementAndGet();
- synchronized (activeTimes) {
- activeTimes.add(Long.valueOf(activeTime));
- activeTimes.poll();
- }
+ activeTimes.add(activeTime);
}
/**
@@ -977,44 +962,6 @@ public abstract class BaseGenericObjectP
return w.toString();
}
- /**
- * Returns the greatest integer less than ore equal to the arithmetic mean
- * of the entries in <code>cache,</code> acquiring and holding the
argument's
- * monitor while making a local copy.
- * @param cache list containing entries to analyze
- * @return truncated arithmetic mean
- */
- private long getMeanFromStatsCache(LinkedList<Long> cache) {
- List<Long> times = new ArrayList<Long>(MEAN_TIMING_STATS_CACHE_SIZE);
- synchronized (cache) {
- times.addAll(cache);
- }
- double result = 0;
- int counter = 0;
- Iterator<Long> iter = times.iterator();
- while (iter.hasNext()) {
- Long time = iter.next();
- if (time != null) {
- counter++;
- result = result * ((counter - 1) / (double) counter) +
- time.longValue()/(double) counter;
- }
- }
- return (long) result;
- }
-
- /**
- * Initializes pool statistics.
- */
- private void initStats() {
- for (int i = 0; i < MEAN_TIMING_STATS_CACHE_SIZE; i++) {
- activeTimes.add(null);
- idleTimes.add(null);
- waitTimes.add(null);
- }
- }
-
-
// Inner classes
/**
@@ -1062,4 +1009,42 @@ public abstract class BaseGenericObjectP
}
}
}
+
+ private class StatsStore {
+
+ private final AtomicLong values[];
+ private final int size;
+ private int index;
+
+ public StatsStore(int size) {
+ this.size = size;
+ values = new AtomicLong[size];
+ for (int i = 0; i < size; i++) {
+ values[i] = new AtomicLong(-1);
+ }
+ }
+
+ public synchronized void add(long value) {
+ values[index].set(value);
+ index++;
+ if (index == size) {
+ index = 0;
+ }
+ }
+
+ public long getMean() {
+ double result = 0;
+ int counter = 0;
+ for (int i = 0; i < size; i++) {
+ long value = values[i].get();
+ if (value != -1) {
+ counter++;
+ result = result * ((counter - 1) / (double) counter) +
+ value/(double) counter;
+ }
+ }
+ return (long) result;
+
+ }
+ }
}