You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by al...@apache.org on 2011/10/13 10:28:43 UTC
svn commit: r1182713 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/cache/
main/java/org/apache/jackrabbit/core/persistence/bundle/
main/java/org/apache/jackrabbit/core/state/
test/java/org/apache/jackrabbit/core/cache/
Author: alexparvulescu
Date: Thu Oct 13 08:28:43 2011
New Revision: 1182713
URL: http://svn.apache.org/viewvc?rev=1182713&view=rev
Log:
JCR-3098 Add hit miss statistics and logging to caches
- patch by Bart van der Schans
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/AbstractCache.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/Cache.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheAccessListener.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/AbstractCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/AbstractCache.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/AbstractCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/AbstractCache.java Thu Oct 13 08:28:43 2011
@@ -65,6 +65,22 @@ public abstract class AbstractCache impl
private final AtomicLong accessCount = new AtomicLong();
/**
+ * Cache access counter. Unike his counterpart {@link #accessCount}, this
+ * does not get reset.
+ *
+ * It is used in the cases where a cache listener needs to call
+ * {@link Cache#resetAccessCount()}, but also needs a total access count. If
+ * you are sure that nobody calls reset, you can just use
+ * {@link #accessCount}.
+ */
+ private final AtomicLong totalAccessCount = new AtomicLong();
+
+ /**
+ * Cache miss counter.
+ */
+ private final AtomicLong missCount = new AtomicLong();
+
+ /**
* Cache access listener. Set in the
* {@link #setAccessListener(CacheAccessListener)} method and accessed
* by periodically by the {@link #recordCacheAccess()} method.
@@ -102,9 +118,14 @@ public abstract class AbstractCache impl
if (count % ACCESS_INTERVAL == 0) {
CacheAccessListener listener = accessListener.get();
if (listener != null) {
- listener.cacheAccessed();
+ listener.cacheAccessed(count);
}
}
+ totalAccessCount.incrementAndGet();
+ }
+
+ protected void recordCacheMiss() {
+ missCount.incrementAndGet();
}
public long getAccessCount() {
@@ -114,6 +135,18 @@ public abstract class AbstractCache impl
public void resetAccessCount() {
accessCount.set(0);
}
+
+ public long getTotalAccessCount(){
+ return totalAccessCount.get();
+ }
+
+ public long getMissCount() {
+ return missCount.get();
+ }
+
+ public void resetMissCount() {
+ missCount.set(0);
+ }
public long getMemoryUsed() {
return memoryUsed.get();
@@ -146,4 +179,25 @@ public abstract class AbstractCache impl
}
}
+ /**
+ * {@inheritDoc}
+ */
+ public String getCacheInfoAsString() {
+ long u = getMemoryUsed() / 1024;
+ long m = getMaxMemorySize() / 1024;
+ StringBuilder c = new StringBuilder();
+ c.append("Cache name=");
+ c.append(this.toString());
+ c.append(", elements=");
+ c.append(getElementCount());
+ c.append(", used memory=");
+ c.append(u);
+ c.append(", max memory=");
+ c.append(m);
+ c.append(", access=");
+ c.append(getTotalAccessCount());
+ c.append(", miss=");
+ c.append(getMissCount());
+ return c.toString();
+ }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/Cache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/Cache.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/Cache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/Cache.java Thu Oct 13 08:28:43 2011
@@ -45,7 +45,6 @@ public interface Cache {
* Get the number of accesses (get or set) until resetAccessCount was called.
* @return the count
*/
-
long getAccessCount();
/**
@@ -54,8 +53,37 @@ public interface Cache {
void resetAccessCount();
/**
+ * Get the total number of cache accesses.
+ * @return the number of hits
+ */
+ long getTotalAccessCount();
+
+ /**
+ * Get the number of cache misses.
+ *
+ * @return the number of misses
+ */
+ long getMissCount();
+
+ /**
+ * Reset the cache miss counter.
+ */
+ void resetMissCount();
+
+ /**
+ * Get the number of elements/objects in the cache.
+ * @return the number of elements
+ */
+ long getElementCount();
+
+ /**
* Add a listener to this cache that is informed after a number of accesses.
*/
void setAccessListener(CacheAccessListener listener);
+ /**
+ * Gathers the stats of the cache for logging.
+ */
+ String getCacheInfoAsString();
+
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheAccessListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheAccessListener.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheAccessListener.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheAccessListener.java Thu Oct 13 08:28:43 2011
@@ -28,9 +28,10 @@ public interface CacheAccessListener {
int ACCESS_INTERVAL = 127;
/**
- * The cache calls this method after a number of accessed.
+ * The cache calls this method after a number of accessed.<br>
+ * For statistical purposes, the cache access count is included
*/
- void cacheAccessed();
+ void cacheAccessed(long accessCount);
/**
* Called after the cache is no longer used.
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheManager.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/CacheManager.java Thu Oct 13 08:28:43 2011
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.core.cache;
import java.util.ArrayList;
+import java.util.List;
import java.util.WeakHashMap;
import org.slf4j.Logger;
@@ -54,6 +55,9 @@ public class CacheManager implements Cac
/** The default minimum resize interval (in ms). */
private static final int DEFAULT_MIN_RESIZE_INTERVAL = 1000;
+ /** The default minimum stats logging interval (in ms). */
+ private static final int DEFAULT_LOG_STATS_INTERVAL = 60 * 1000;
+
/** The size of a big object, to detect if a cache is full or not. */
private static final int BIG_OBJECT_SIZE = 16 * 1024;
@@ -77,11 +81,21 @@ public class CacheManager implements Cac
"org.apache.jackrabbit.cacheResizeInterval",
DEFAULT_MIN_RESIZE_INTERVAL);
- /** The last time the caches where resized. */
+ /** The minimum interval time between stats are logged */
+ private long minLogStatsInterval = Long.getLong(
+ "org.apache.jackrabbit.cacheLogStatsInterval",
+ DEFAULT_LOG_STATS_INTERVAL);
+
+ /** The last time the caches where resized. */
private volatile long nextResize =
System.currentTimeMillis() + DEFAULT_MIN_RESIZE_INTERVAL;
+ /** The last time the cache stats were logged. */
+ private volatile long nextLogStats =
+ System.currentTimeMillis() + DEFAULT_LOG_STATS_INTERVAL;
+
+
public long getMaxMemory() {
return maxMemory;
}
@@ -118,7 +132,10 @@ public class CacheManager implements Cac
* After one of the caches is accessed a number of times, this method is called.
* Resize the caches if required.
*/
- public void cacheAccessed() {
+ public void cacheAccessed(long accessCount) {
+
+ logCacheStats();
+
long now = System.currentTimeMillis();
if (now < nextResize) {
return;
@@ -136,7 +153,22 @@ public class CacheManager implements Cac
}
/**
- * Re-calcualte the maximum memory for each cache, and set the new limits.
+ * Log info about the caches.
+ */
+ private void logCacheStats() {
+ if (log.isDebugEnabled()) {
+ long now = System.currentTimeMillis();
+ if (now < nextLogStats) {
+ return;
+ }
+ for (Cache cache : caches.keySet()) {
+ log.debug(cache.getCacheInfoAsString());
+ }
+ nextLogStats = now + minLogStatsInterval;
+ }
+ }
+ /**
+ * Re-calculate the maximum memory for each cache, and set the new limits.
*/
private void resizeAll() {
if (log.isDebugEnabled()) {
@@ -146,11 +178,9 @@ public class CacheManager implements Cac
// entries in a weak hash map may disappear any time
// so can't use size() / keySet() directly
// only using the iterator guarantees that we don't get null references
- ArrayList<Cache> list = new ArrayList<Cache>();
+ List<Cache> list = new ArrayList<Cache>();
synchronized (caches) {
- for (Cache c: caches.keySet()) {
- list.add(c);
- }
+ list.addAll(caches.keySet());
}
if (list.size() == 0) {
// nothing to do
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cache/ConcurrentCache.java Thu Oct 13 08:28:43 2011
@@ -57,10 +57,12 @@ public class ConcurrentCache<K, V> exten
}
+ private final String name;
private final Map<K, E<V>>[] segments;
@SuppressWarnings({ "unchecked", "serial" })
- public ConcurrentCache(int numberOfSegments) {
+ public ConcurrentCache(String name, int numberOfSegments) {
+ this.name = name;
this.segments = new Map[numberOfSegments];
for (int i = 0; i < segments.length; i++) {
segments[i] = new LinkedHashMap<K, E<V>>(16, 0.75f, true) {
@@ -77,8 +79,8 @@ public class ConcurrentCache<K, V> exten
}
}
- public ConcurrentCache() {
- this(DEFAULT_NUMBER_OF_SEGMENTS);
+ public ConcurrentCache(String name) {
+ this(name, DEFAULT_NUMBER_OF_SEGMENTS);
}
/**
@@ -124,10 +126,10 @@ public class ConcurrentCache<K, V> exten
E<V> entry = segment.get(key);
if (entry != null) {
return entry.value;
- } else {
- return null;
}
}
+ recordCacheMiss();
+ return null;
}
/**
@@ -252,4 +254,17 @@ public class ConcurrentCache<K, V> exten
}
}
+ public long getElementCount() {
+ long count = 0;
+ for (int i = 0; i < segments.length; i++) {
+ count += segments[i].size();
+ }
+ return count;
+ }
+
+ @Override
+ public String toString() {
+ return name + "[" + getClass().getSimpleName() + "@"
+ + Integer.toHexString(hashCode()) + "]";
+ }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java Thu Oct 13 08:28:43 2011
@@ -377,7 +377,7 @@ public abstract class AbstractBundlePers
public void init(PMContext context) throws Exception {
this.context = context;
// init bundle cache
- bundles = new ConcurrentCache<NodeId, NodePropBundle>();
+ bundles = new ConcurrentCache<NodeId, NodePropBundle>(context.getHomeDir().getName() + "BundleCache");
bundles.setMaxMemorySize(bundleCacheSize);
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/MLRUItemStateCache.java Thu Oct 13 08:28:43 2011
@@ -45,7 +45,7 @@ public class MLRUItemStateCache implemen
private volatile long numWrites = 0;
private final ConcurrentCache<ItemId, ItemState> cache =
- new ConcurrentCache<ItemId, ItemState>();
+ new ConcurrentCache<ItemId, ItemState>(MLRUItemStateCache.class.getSimpleName());
public MLRUItemStateCache(CacheManager cacheMgr) {
cache.setMaxMemorySize(DEFAULT_MAX_MEM);
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java?rev=1182713&r1=1182712&r2=1182713&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java Thu Oct 13 08:28:43 2011
@@ -37,7 +37,7 @@ public class ConcurrentCacheTest extends
}
ConcurrentCache<NodeId, NodeId> cache =
- new ConcurrentCache<NodeId, NodeId>();
+ new ConcurrentCache<NodeId, NodeId>("test");
cache.setMaxMemorySize(ids.length / 2);
for (int i = 0; i < ids.length; i++) {