OPENJPA-1739 Added additional metrics to cache statistics and updated instrumentation.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@984896 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jeremy Bauer 2010-08-12 18:18:43 +00:00
parent 7bfc33e468
commit a36ace562b
10 changed files with 291 additions and 53 deletions

View File

@ -82,6 +82,14 @@ public class TestJMXPlatformMBeans extends AbstractPersistenceTestCase {
assertTrue(oemf.getCache().contains(CachedEntity.class, id));
ce = oem.find(CachedEntity.class, id);
assertTrue(dci.getHitCount() > 0);
try {
assertTrue(dci.getHitCount(CachedEntity.class.getName()) > 0);
} catch (ClassNotFoundException e) {
fail("CachedEntity class not found");
}
assertTrue(dci.getWriteCount() > 0);
assertTrue(dci.classNames().contains(CachedEntity.class.getName()));
// Thread out to do out-of-band MBean-based validation. This could
// have been done on the same thread, but threading out makes for a
// more realistic test.
@ -271,6 +279,9 @@ public class TestJMXPlatformMBeans extends AbstractPersistenceTestCase {
assertTrue(clsHitCount > 0);
assertTrue(clsReadCount > 0);
assertTrue(clsWriteCount > 0);
Set<String> classNames = (Set<String>)mbs.invoke(on, "classNames", null, null);
assertNotNull(classNames);
assertTrue(classNames.contains(CachedEntity.class.getName()));
// Invoke the reset method and recollect stats
mbs.invoke(on, "reset", null, null);
hitCount = (Long)mbs.getAttribute(on, "HitCount");

View File

@ -152,7 +152,11 @@ public class PreparedQueryCacheImpl implements PreparedQueryCache {
try {
if (_log != null && _log.isTraceEnabled())
_log.trace(_loc.get("prepared-query-invalidate", id));
return _delegate.remove(id) != null;
boolean rc = _delegate.remove(id) != null;
if (_statsEnabled && rc) {
_stats.recordEviction(id);
}
return rc;
} finally {
unlock(false);
}
@ -187,7 +191,11 @@ public class PreparedQueryCacheImpl implements PreparedQueryCache {
if (_log != null && _log.isTraceEnabled())
_log.trace(_loc.get("prepared-query-uncache", id, exclusion));
}
return _delegate.remove(id);
PreparedQuery pq = _delegate.remove(id);
if (_statsEnabled && pq != null) {
_stats.recordEviction(id);
}
return pq;
} finally {
unlock(false);
}

View File

@ -40,8 +40,6 @@ import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.concurrent.AbstractConcurrentEventManager;
import org.apache.openjpa.util.GeneralException;
import org.apache.openjpa.util.OpenJPAException;
import serp.util.Strings;
/**
@ -235,6 +233,9 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
public DataCachePCData remove(Object key) {
DataCachePCData o = removeInternal(key);
if (stats.isEnabled()) {
stats.newEvict(o == null ? null : o.getType());
}
if (o != null && o.isTimedOut())
o = null;
if (log.isTraceEnabled()) {

View File

@ -187,6 +187,9 @@ public abstract class AbstractQueryCache
public QueryResult remove(QueryKey key) {
QueryResult o = removeInternal(key);
if (_statsEnabled) {
_stats.recordEviction(key);
}
if (o != null && o.isTimedOut())
o = null;
if (log.isTraceEnabled()) {
@ -448,6 +451,10 @@ public abstract class AbstractQueryCache
return _name;
}
public int count() {
return keySet().size();
}
/**
* A default implementation of query statistics for the Query result cache.
*
@ -463,9 +470,10 @@ public abstract class AbstractQueryCache
private static final float LOAD_FACTOR = 0.75f;
private static final int CONCURRENCY = 16;
private static final int ARRAY_SIZE = 2;
private static final int ARRAY_SIZE = 3;
private static final int READ = 0;
private static final int HIT = 1;
private static final int EVICT = 2;
private long[] astat = new long[ARRAY_SIZE];
private long[] stat = new long[ARRAY_SIZE];
@ -510,6 +518,14 @@ public abstract class AbstractQueryCache
return getCount(astats, query, HIT);
}
public long getEvictionCount() {
return stat[EVICT];
}
public long getTotalEvictionCount() {
return astat[EVICT];
}
private long getCount(Map<T, long[]> target, T query, int i) {
long[] row = target.get(query);
return (row == null) ? 0 : row[i];
@ -565,6 +581,12 @@ public abstract class AbstractQueryCache
addSample(query, HIT);
}
public void recordEviction(T query) {
if (query == null)
return;
addSample(query, EVICT);
}
public void dump(PrintStream out) {
String header = "Query Statistics starting from " + start;
out.print(header);

View File

@ -22,6 +22,7 @@ import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Counts number of read/write requests and hit ratio for a cache in total and
@ -74,34 +75,54 @@ public interface CacheStatistics extends Serializable {
/**
* Gets number of total read requests for the given class since last reset.
*/
public long getReadCount(Class c);
public long getReadCount(Class<?> c);
/**
* Gets number of total read requests that has been found in cache for the
* given class since last reset.
*/
public long getHitCount(Class c);
public long getHitCount(Class<?> c);
/**
* Gets number of total write requests for the given class since last reset.
*/
public long getWriteCount(Class c);
public long getWriteCount(Class<?> c);
/**
* Gets number of total read requests for the given class since start.
*/
public long getTotalReadCount(Class c);
public long getTotalReadCount(Class<?> c);
/**
* Gets number of total read requests that has been found in cache for the
* given class since start.
*/
public long getTotalHitCount(Class c);
public long getTotalHitCount(Class<?> c);
/**
* Gets number of total write requests for the given class since start.
*/
public long getTotalWriteCount(Class c);
public long getTotalWriteCount(Class<?> c);
/**
* Gets number of total evictions since last reset.
*/
public long getEvictionCount();
/**
* Gets number of total evictions for the given class since last reset.
*/
public long getEvictionCount(Class<?> c);
/**
* Gets number of total evictions in cache since start.
*/
public long getTotalEvictionCount();
/**
* Gets number of total evictions for the given class since start.
*/
public long getTotalEvictionCount(Class<?> c);
/**
* Gets the time of last reset.
@ -123,15 +144,22 @@ public interface CacheStatistics extends Serializable {
*/
public boolean isEnabled();
/**
* Returns the classes being tracked.
* @return
*/
public Set<Class<?>> classNames();
/**
* A default implementation.
*
*/
public static class Default implements CacheStatistics {
private long[] astat = new long[3];
private long[] stat = new long[3];
private Map<Class, long[]> stats = new HashMap<Class, long[]>();
private Map<Class, long[]> astats = new HashMap<Class, long[]>();
private static final int ARRAY_SIZE = 4;
private long[] astat = new long[ARRAY_SIZE];
private long[] stat = new long[ARRAY_SIZE];
private Map<Class<?>, long[]> stats = new HashMap<Class<?>, long[]>();
private Map<Class<?>, long[]> astats = new HashMap<Class<?>, long[]>();
private Date start = new Date();
private Date since = new Date();
private boolean enabled = false;
@ -139,6 +167,7 @@ public interface CacheStatistics extends Serializable {
private static final int READ = 0;
private static final int HIT = 1;
private static final int WRITE = 2;
private static final int EVICT = 3;
public long getReadCount() {
return stat[READ];
@ -152,6 +181,10 @@ public interface CacheStatistics extends Serializable {
return stat[WRITE];
}
public long getEvictionCount() {
return stat[EVICT];
}
public long getTotalReadCount() {
return astat[READ];
}
@ -164,31 +197,43 @@ public interface CacheStatistics extends Serializable {
return astat[WRITE];
}
public long getReadCount(Class c) {
public long getTotalEvictionCount() {
return astat[EVICT];
}
public long getReadCount(Class<?> c) {
return getCount(stats, c, READ);
}
public long getHitCount(Class c) {
public long getHitCount(Class<?> c) {
return getCount(stats, c, HIT);
}
public long getWriteCount(Class c) {
public long getWriteCount(Class<?> c) {
return getCount(stats, c, WRITE);
}
public long getTotalReadCount(Class c) {
public long getEvictionCount(Class<?> c) {
return getCount(stats, c, EVICT);
}
public long getTotalReadCount(Class<?> c) {
return getCount(astats, c, READ);
}
public long getTotalHitCount(Class c) {
public long getTotalHitCount(Class<?> c) {
return getCount(astats, c, HIT);
}
public long getTotalWriteCount(Class c) {
public long getTotalWriteCount(Class<?> c) {
return getCount(astats, c, WRITE);
}
private long getCount(Map<Class, long[]> target, Class c, int index) {
public long getTotalEvictionCount(Class<?> c) {
return getCount(astats, c, EVICT);
}
private long getCount(Map<Class<?>, long[]> target, Class<?> c, int index) {
long[] row = target.get(c);
return (row == null) ? 0 : row[index];
}
@ -202,7 +247,7 @@ public interface CacheStatistics extends Serializable {
}
public void reset() {
stat = new long[3];
stat = new long[ARRAY_SIZE];
stats.clear();
since = new Date();
}
@ -216,7 +261,7 @@ public interface CacheStatistics extends Serializable {
void disable() {
enabled = false;
}
void newGet(Class cls, boolean hit) {
void newGet(Class<?> cls, boolean hit) {
cls = (cls == null) ? Object.class : cls;
addSample(cls, READ);
if (hit) {
@ -224,25 +269,34 @@ public interface CacheStatistics extends Serializable {
}
}
void newPut(Class cls) {
void newPut(Class<?> cls) {
cls = (cls == null) ? Object.class : cls;
addSample(cls, WRITE);
}
private void addSample(Class c, int index) {
void newEvict(Class<?> cls) {
cls = (cls == null) ? Object.class : cls;
addSample(cls, EVICT);
}
private void addSample(Class<?> c, int index) {
stat[index]++;
astat[index]++;
addSample(stats, c, index);
addSample(astats, c, index);
}
private void addSample(Map<Class, long[]> target, Class c, int index) {
private void addSample(Map<Class<?>, long[]> target, Class<?> c, int index) {
long[] row = target.get(c);
if (row == null) {
row = new long[3];
row = new long[ARRAY_SIZE];
}
row[index]++;
target.put(c, row);
}
public Set<Class<?>> classNames() {
return astats.keySet();
}
}
}

View File

@ -18,7 +18,10 @@
*/
package org.apache.openjpa.instrumentation;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.apache.openjpa.datacache.CacheStatistics;
import org.apache.openjpa.datacache.DataCache;
@ -152,22 +155,6 @@ public abstract class AbstractDataCacheInstrument extends AbstractInstrument
return null;
}
public long getEvictionCount() {
CacheStatistics stats = getStatistics();
// TODO : Implement eviction count in data cache stats
// if (stats != null)
// return stats.getEvictionCount();
return NO_STATS;
}
public long getTotalEvictionCount() {
CacheStatistics stats = getStatistics();
// TODO : Implement eviction count in data cache stats
// if (stats != null)
// return stats.getTotalEvictionCount();
return NO_STATS;
}
public String getConfigId() {
return _configID;
}
@ -231,8 +218,63 @@ public abstract class AbstractDataCacheInstrument extends AbstractInstrument
return NO_STATS;
}
public long getEvictionCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getEvictionCount();
return NO_STATS;
}
public long getEvictionCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getEvictionCount(clazz);
}
public long getEvictionCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getEvictionCount(c);
return NO_STATS;
}
public long getTotalEvictionCount() {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalEvictionCount();
return NO_STATS;
}
public long getTotalEvictionCount(String className)
throws ClassNotFoundException {
Class<?> clazz = Class.forName(className);
return getTotalEvictionCount(clazz);
}
public long getTotalEvictionCount(Class<?> c) {
CacheStatistics stats = getStatistics();
if (stats != null)
return stats.getTotalEvictionCount(c);
return NO_STATS;
}
@SuppressWarnings("unchecked")
public Set<String> classNames() {
CacheStatistics stats = getStatistics();
if (stats != null) {
Set<String> classNames = new HashSet<String>();
Set<Class<?>> clazzNames = stats.classNames();
for (Class<?> clazz : clazzNames) {
if (clazz != null) {
classNames.add(clazz.getName());
}
}
return classNames;
}
return Collections.EMPTY_SET;
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}
}

View File

@ -22,6 +22,7 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.apache.openjpa.datacache.AbstractQueryCache;
import org.apache.openjpa.datacache.QueryCache;
import org.apache.openjpa.datacache.QueryKey;
import org.apache.openjpa.kernel.QueryStatistics;
@ -159,6 +160,26 @@ public abstract class AbstractQueryCacheInstrument extends AbstractInstrument
return null;
}
/**
* Returns number of total evictions since last reset
*/
public long getEvictionCount() {
QueryStatistics<QueryKey> stats = getStatistics();
if (stats != null)
return stats.getEvictionCount();
return NO_STATS;
}
/**
* Returns number of total eviction requests since start.
*/
public long getTotalEvictionCount() {
QueryStatistics<QueryKey> stats = getStatistics();
if (stats != null)
return stats.getTotalEvictionCount();
return NO_STATS;
}
/**
* Returns all query keys currently tracked in the cache.
* @return
@ -185,6 +206,17 @@ public abstract class AbstractQueryCacheInstrument extends AbstractInstrument
return null;
}
public long count() {
if (_qc == null) {
return NO_STATS;
}
if (_qc instanceof AbstractQueryCache) {
AbstractQueryCache aqc = (AbstractQueryCache)_qc;
return aqc.count();
}
return NO_STATS;
}
public InstrumentationLevel getLevel() {
return InstrumentationLevel.FACTORY;
}

View File

@ -19,6 +19,7 @@
package org.apache.openjpa.instrumentation;
import java.util.Date;
import java.util.Set;
/**
* Interface for providing instrumented data cache metrics and operations.
@ -119,4 +120,9 @@ public interface DataCacheInstrument {
* Returns date cache statistics collection started.
*/
public Date startDate();
/**
* Returns the names of classes currently tracked in the cache.
*/
public Set<String> classNames();
}

View File

@ -32,7 +32,8 @@ public interface QueryCacheInstrument {
public long getTotalExecutionCount();
/**
* Returns number of total exec requests since start.
* Returns number of total exec requests since start for
* the specified string-ified query key.
*/
public long getTotalExecutionCount(String queryKey);
@ -42,7 +43,8 @@ public interface QueryCacheInstrument {
public long getExecutionCount();
/**
* Returns number of total execution requests since last reset
* Returns number of total execution requests since last reset for
* the specified string-ified query key.
*/
public long getExecutionCount(String queryKey);
@ -54,7 +56,7 @@ public interface QueryCacheInstrument {
/**
* Returns number of total read requests that have been found in cache since
* last reset.
* last reset for the specified string-ified query key.
*/
public long getHitCount(String queryKey);
@ -64,7 +66,8 @@ public interface QueryCacheInstrument {
public long getTotalHitCount();
/**
* Returns number of total read requests that has been found since start.
* Returns number of total read requests that has been found since start for
* the specified string-ified query key.
*/
public long getTotalHitCount(String queryKey);
@ -84,8 +87,25 @@ public interface QueryCacheInstrument {
public Date startDate();
/**
* Returns all query keys currently in the cache.
* Returns all the string-ified keys for query results in the cache.
* @return
*/
public Set<String> queryKeys();
/**
* Returns number of total evictions since last reset
*/
public long getEvictionCount();
/**
* Returns number of total eviction requests since start.
*/
public long getTotalEvictionCount();
/**
* Returns the number of total entries in the cache.
* @return entries
*/
public long count();
}

View File

@ -52,6 +52,11 @@ public interface QueryStatistics<T> extends Serializable {
*/
void recordExecution(T query);
/**
* Record that the given query has been evicted.
*/
void recordEviction(T query);
/**
* Gets number of total query execution since last reset.
*/
@ -94,6 +99,16 @@ public interface QueryStatistics<T> extends Serializable {
*/
public long getTotalHitCount(T query);
/**
* Gets number of total query evictions since last reset.
*/
public long getEvictionCount();
/**
* Gets number of total query evictions since start.
*/
public long getTotalEvictionCount();
/**
* Gets the time of last reset.
*/
@ -131,9 +146,10 @@ public interface QueryStatistics<T> extends Serializable {
private static final float LOAD_FACTOR = 0.75f;
private static final int CONCURRENCY = 16;
private static final int ARRAY_SIZE = 2;
private static final int ARRAY_SIZE = 3;
private static final int READ = 0;
private static final int HIT = 1;
private static final int EVICT = 2;
private long[] astat = new long[ARRAY_SIZE];
private long[] stat = new long[ARRAY_SIZE];
@ -232,6 +248,13 @@ public interface QueryStatistics<T> extends Serializable {
addSample(query, HIT);
}
public void recordEviction(T query) {
if (query == null) {
return;
}
addSample(query, EVICT);
}
public void dump(PrintStream out) {
String header = "Query Statistics starting from " + start;
out.print(header);
@ -267,6 +290,14 @@ public interface QueryStatistics<T> extends Serializable {
String toString(long[] row) {
return row[READ] + ":" + row[HIT] + "(" + pct(row[HIT], row[READ]) + "%)";
}
public long getEvictionCount() {
return stat[EVICT];
}
public long getTotalEvictionCount() {
return astat[EVICT];
}
}
/**
@ -318,6 +349,14 @@ public interface QueryStatistics<T> extends Serializable {
return 0;
}
public long getEvictionCount() {
return 0;
}
public long getTotalEvictionCount() {
return 0;
}
public Set<T> keys() {
return Collections.emptySet();
}
@ -337,6 +376,9 @@ public interface QueryStatistics<T> extends Serializable {
public Date start() {
return start;
}
public void recordEviction(T query) {
}
}
}