You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2010/10/05 23:12:53 UTC
svn commit: r1004818 - in /openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/datacache/
openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/
Author: curtisr7
Date: Tue Oct 5 21:12:52 2010
New Revision: 1004818
URL: http://svn.apache.org/viewvc?rev=1004818&view=rev
Log:
OPENJPA-1801: Refactor cache statistics.
Added:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java (with props)
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java (with props)
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java?rev=1004818&r1=1004817&r2=1004818&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java Tue Oct 5 21:12:52 2010
@@ -34,12 +34,16 @@ import org.apache.commons.lang.StringUti
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.event.RemoteCommitEvent;
import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
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.InternalException;
+import org.apache.openjpa.util.OpenJPAId;
+
import serp.util.Strings;
/**
@@ -54,7 +58,7 @@ import serp.util.Strings;
public abstract class AbstractDataCache extends AbstractConcurrentEventManager
implements DataCache, Configurable {
- protected CacheStatistics.Default stats = new CacheStatistics.Default();
+ protected CacheStatisticsSPI _stats = new CacheStatisticsImpl();
private static final BitSet EMPTY_BITSET = new BitSet(0);
@@ -86,11 +90,11 @@ public abstract class AbstractDataCache
}
public void setEnableStatistics(boolean enable){
if(enable == true){
- stats.enable();
+ _stats.enable();
}
}
public void getEnableStatistics(){
- stats.isEnabled();
+ _stats.isEnabled();
}
public String getEvictionSchedule() {
@@ -157,9 +161,6 @@ public abstract class AbstractDataCache
public boolean contains(Object key) {
DataCachePCData o = getInternal(key);
- if (stats.isEnabled()) {
- stats.newGet(o == null ? null : o.getType(), o != null);
- }
if (o != null && o.isTimedOut()) {
o = null;
removeInternal(key);
@@ -195,9 +196,7 @@ public abstract class AbstractDataCache
else
log.trace(s_loc.get("cache-hit", key));
}
- if (stats.isEnabled()) {
- stats.newGet((o == null) ? null : o.getType(), o != null);
- }
+
return o;
}
@@ -213,9 +212,6 @@ public abstract class AbstractDataCache
}
public DataCachePCData put(DataCachePCData data) {
- if (stats.isEnabled()) {
- stats.newPut(data.getType());
- }
DataCachePCData o = putInternal(data.getId(), data);
if (log.isTraceEnabled())
log.trace(s_loc.get("cache-put", data.getId()));
@@ -224,18 +220,12 @@ public abstract class AbstractDataCache
public void update(DataCachePCData data) {
if (recacheUpdates()) {
- if (stats.isEnabled()) {
- stats.newPut(data.getType());
- }
putInternal(data.getId(), data);
}
}
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()) {
@@ -418,9 +408,6 @@ public abstract class AbstractDataCache
*/
protected void putAllInternal(Collection<DataCachePCData> pcs) {
for (DataCachePCData pc : pcs) {
- if (stats.isEnabled()) {
- stats.newPut(pc.getType());
- }
putInternal(pc.getId(), pc);
}
}
@@ -492,9 +479,9 @@ public abstract class AbstractDataCache
public boolean isPartitioned() {
return false;
}
-
- public CacheStatistics getStatistics() {
- return stats;
+
+ public CacheStatistics getStatistics() {
+ return _stats;
}
// ---------- Configurable implementation ----------
@@ -550,4 +537,8 @@ public abstract class AbstractDataCache
_excludedTypes =
StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0)));
}
+
+ public DataCache selectCache(OpenJPAStateManager sm) {
+ return this;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java?rev=1004818&r1=1004817&r2=1004818&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatistics.java Tue Oct 5 21:12:52 2010
@@ -24,6 +24,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import org.apache.openjpa.util.OpenJPAId;
+
/**
* Counts number of read/write requests and hit ratio for a cache in total and
* per-class basis.
@@ -35,11 +37,9 @@ import java.util.Set;
* is registered under generic <code>java.lang.Object</code>.
*
* @since 1.3.0
- *
- * @author Pinaki Poddar
- *
*/
public interface CacheStatistics extends Serializable {
+
/**
* Gets number of total read requests since last reset.
*/
@@ -104,26 +104,6 @@ public interface CacheStatistics extends
*/
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.
*/
@@ -149,154 +129,5 @@ public interface CacheStatistics extends
* @return
*/
public Set<Class<?>> classNames();
-
- /**
- * A default implementation.
- *
- */
- public static class Default implements CacheStatistics {
- 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;
-
- 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];
- }
-
- public long getHitCount() {
- return stat[HIT];
- }
-
- public long getWriteCount() {
- return stat[WRITE];
- }
-
- public long getEvictionCount() {
- return stat[EVICT];
- }
-
- public long getTotalReadCount() {
- return astat[READ];
- }
-
- public long getTotalHitCount() {
- return astat[HIT];
- }
-
- public long getTotalWriteCount() {
- return astat[WRITE];
- }
-
- public long getTotalEvictionCount() {
- return astat[EVICT];
- }
-
- public long getReadCount(Class<?> c) {
- return getCount(stats, c, READ);
- }
-
- public long getHitCount(Class<?> c) {
- return getCount(stats, c, HIT);
- }
-
- public long getWriteCount(Class<?> c) {
- return getCount(stats, c, WRITE);
- }
-
- 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) {
- return getCount(astats, c, HIT);
- }
-
- public long getTotalWriteCount(Class<?> c) {
- return getCount(astats, c, WRITE);
- }
-
- 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];
- }
-
- public Date since() {
- return since;
- }
-
- public Date start() {
- return start;
- }
-
- public void reset() {
- stat = new long[ARRAY_SIZE];
- stats.clear();
- since = new Date();
- }
-
- public boolean isEnabled() {
- return enabled;
- }
- void enable(){
- enabled = true;
- }
- void disable() {
- enabled = false;
- }
- void newGet(Class<?> cls, boolean hit) {
- cls = (cls == null) ? Object.class : cls;
- addSample(cls, READ);
- if (hit) {
- addSample(cls, HIT);
- }
- }
-
- void newPut(Class<?> cls) {
- cls = (cls == null) ? Object.class : cls;
- addSample(cls, WRITE);
- }
-
- 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) {
- long[] row = target.get(c);
- if (row == null) {
- row = new long[ARRAY_SIZE];
- }
- row[index]++;
- target.put(c, row);
- }
- public Set<Class<?>> classNames() {
- return astats.keySet();
- }
- }
}
Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java?rev=1004818&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java Tue Oct 5 21:12:52 2010
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.datacache;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.openjpa.util.OpenJPAId;
+
+/**
+ * The default CacheStatistics(SPI) implementation.
+ */
+public class CacheStatisticsImpl implements CacheStatisticsSPI {
+ private static final long serialVersionUID = 9014495759588003166L;
+ private static final int ARRAY_SIZE = 3;
+ 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;
+
+ private static final int READ = 0;
+ private static final int HIT = 1;
+ private static final int WRITE = 2;
+
+ public long getReadCount() {
+ return stat[READ];
+ }
+
+ public long getHitCount() {
+ return stat[HIT];
+ }
+
+ public long getWriteCount() {
+ return stat[WRITE];
+ }
+
+ public long getTotalReadCount() {
+ return astat[READ];
+ }
+
+ public long getTotalHitCount() {
+ return astat[HIT];
+ }
+
+ public long getTotalWriteCount() {
+ return astat[WRITE];
+ }
+
+ public long getReadCount(Class<?> c) {
+ return getCount(stats, c, READ);
+ }
+
+ public long getHitCount(Class<?> c) {
+ return getCount(stats, c, HIT);
+ }
+
+ public long getWriteCount(Class<?> c) {
+ return getCount(stats, c, WRITE);
+ }
+
+ public long getTotalReadCount(Class<?> c) {
+ return getCount(astats, c, READ);
+ }
+
+ public long getTotalHitCount(Class<?> c) {
+ return getCount(astats, c, HIT);
+ }
+
+ public long getTotalWriteCount(Class<?> c) {
+ return getCount(astats, c, WRITE);
+ }
+
+ public Date since() {
+ return since;
+ }
+
+ public Date start() {
+ return start;
+ }
+
+ public void reset() {
+ stat = new long[ARRAY_SIZE];
+ stats.clear();
+ since = new Date();
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public Set<Class<?>> classNames() {
+ return astats.keySet();
+ }
+
+ /**
+ * SPI implementation
+ */
+ public void enable() {
+ enabled = true;
+ }
+
+ public void disable() {
+ enabled = false;
+ }
+
+ public void newGet(Class<?> cls, boolean hit) {
+ if (!enabled) {
+ return;
+ }
+ if (cls == null) {
+ throw new RuntimeException("Snap! newGet will null cls Name");
+ }
+ cls = (cls == null) ? Object.class : cls;
+ addSample(cls, READ);
+ if (hit) {
+ addSample(cls, HIT);
+ }
+ }
+
+ public void newGet(Object oid, boolean hit) {
+ if (!enabled) {
+ return;
+ }
+ if (oid instanceof OpenJPAId) {
+ newGet(((OpenJPAId) oid).getType(), hit);
+ }
+ }
+
+ public void newPut(Class<?> cls) {
+ if (!enabled) {
+ return;
+ }
+ cls = (cls == null) ? Object.class : cls;
+ addSample(cls, WRITE);
+ }
+
+ public void newPut(Object oid) {
+ if (!enabled) {
+ return;
+ }
+ if (oid instanceof OpenJPAId) {
+ newPut(((OpenJPAId) oid).getType());
+ }
+ }
+
+ /**
+ * Private worker methods.
+ */
+ 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) {
+ long[] row = target.get(c);
+ if (row == null) {
+ row = new long[ARRAY_SIZE];
+ }
+ row[index]++;
+ target.put(c, row);
+ }
+
+ private long getCount(Map<Class<?>, long[]> target, Class<?> c, int index) {
+ long[] row = target.get(c);
+ return (row == null) ? 0 : row[index];
+ }
+}
Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java?rev=1004818&view=auto
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java (added)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java Tue Oct 5 21:12:52 2010
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.datacache;
+
+/**
+ * The provider extensions to the CacheStatistics interface.
+ */
+public interface CacheStatisticsSPI extends CacheStatistics {
+ /**
+ * Record a new cache get.
+ *
+ * @param cls
+ * - The class describing the type that is contained in the cache.
+ * @param hit
+ * - true for a cache hit, false otherwise
+ */
+ public void newGet(Class<?> cls, boolean hit);
+
+ /**
+ * Record a new cache get.
+ *
+ * @param oid
+ * - The cache key.
+ * @param hit
+ * - true for a cache hit, false otherwise
+ */
+ public void newGet(Object oid, boolean hit);
+
+ /**
+ * Record a new cache put.
+ *
+ * @param cls
+ * - The class describing the type that is contained in the cache.
+ */
+ public void newPut(Class<?> cls);
+
+ /**
+ * Record a new cache put.
+ *
+ * @param oid
+ * - The cache key.
+ */
+ public void newPut(Object oid);
+
+ /**
+ * Enable statistics collection.
+ */
+ public void enable();
+
+ /**
+ * Disable statistics collection.
+ */
+ public void disable();
+}
Propchange: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/CacheStatisticsSPI.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?rev=1004818&r1=1004817&r2=1004818&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java Tue Oct 5 21:12:52 2010
@@ -147,6 +147,10 @@ public class DataCacheStoreManager
data = newPCData(sm);
data.store(sm);
mods.additions.add(new PCDataHolder(data, sm));
+ CacheStatistics stats = cache.getStatistics();
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newPut(sm.getMetaData().getDescribedType());
+ }
}
}
@@ -182,6 +186,10 @@ public class DataCacheStoreManager
data.store(sm, fields);
mods.existingUpdates.add(new PCDataHolder(data, sm));
}
+ CacheStatistics stats = cache.getStatistics();
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newPut(sm.getMetaData().getDescribedType());
+ }
}
}
@@ -272,9 +280,22 @@ public class DataCacheStoreManager
}
public boolean exists(OpenJPAStateManager sm, Object edata) {
- DataCache cache = _mgr.selectCache(sm);
- if (cache != null && !isLocking(null) && cache.contains(sm.getObjectId()))
+ DataCache cache = _mgr.selectCache(sm);
+ CacheStatistics stats = cache.getStatistics();
+ if (cache != null && !isLocking(null) && cache.contains(sm.getObjectId())){
+ if (stats.isEnabled()) {
+ // delay this call ONLY if stats collection is enabled
+ Class<?> cls = sm.getMetaData().getDescribedType();
+ ((CacheStatisticsSPI)stats).newGet(cls, false);
+ }
return true;
+ }
+ // If isLocking(null)==true && cache.contains(..) == true... probably shouldn't count?
+ if (stats.isEnabled()) {
+ // delay this call ONLY if stats collection is enabled
+ Class<?> cls = sm.getMetaData().getDescribedType();
+ ((CacheStatisticsSPI)stats).newGet(cls, false);
+ }
return super.exists(sm, edata);
}
@@ -301,7 +322,11 @@ public class DataCacheStoreManager
public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
DataCache cache = _mgr.selectCache(sm);
FetchConfiguration fc = sm.getContext().getFetchConfiguration();
+ CacheStatistics stats = cache.getStatistics();
if (cache == null || sm.isEmbedded() || fc.getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS) {
+ if(stats.isEnabled()){
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), false);
+ }
return super.syncVersion(sm, edata);
}
@@ -313,6 +338,9 @@ public class DataCacheStoreManager
// if we have a cached version update from there
if (version != null) {
+ if(stats.isEnabled()){
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), true);
+ }
if (!version.equals(sm.getVersion())) {
sm.setVersion(version);
return false;
@@ -320,6 +348,9 @@ public class DataCacheStoreManager
return true;
}
+ if(stats.isEnabled()){
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), false);
+ }
// use data store version
return super.syncVersion(sm, edata);
}
@@ -329,18 +360,29 @@ public class DataCacheStoreManager
if (cache == null) {
return super.initialize(sm, state, fetch, edata);
}
+ Class<?> cls = sm.getMetaData().getDescribedType();
DataCachePCData data = cache.get(sm.getObjectId());
+ CacheStatistics stats = cache.getStatistics();
boolean fromDatabase = false;
boolean alreadyCached = data != null;
if (sm.isEmbedded()
|| fetch.getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS
|| fetch.getCacheStoreMode() == DataCacheStoreMode.REFRESH) {
+ // stats -- Skipped reading from the cache, noop
fromDatabase = super.initialize(sm, state, fetch, edata);
} else {
- if (alreadyCached && !isLocking(fetch)) {
- sm.initialize(data.getType(), state);
+ if (alreadyCached && !isLocking(fetch)) {
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(cls, true);
+ }
+ sm.initialize(cls, state);
data.load(sm, fetch, edata);
} else {
+ if (!alreadyCached) {
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(cls, false);
+ }
+ }
fromDatabase = super.initialize(sm, state, fetch, edata);
}
}
@@ -349,6 +391,9 @@ public class DataCacheStoreManager
&& ((fetch.getCacheStoreMode() == DataCacheStoreMode.USE && !alreadyCached)
|| (fetch.getCacheStoreMode() == DataCacheStoreMode.REFRESH));
if (updateCache) {
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newPut(cls);
+ }
cacheStateManager(cache, sm, data);
}
return fromDatabase || alreadyCached;
@@ -389,11 +434,17 @@ public class DataCacheStoreManager
if (cache == null || sm.isEmbedded() || bypass(fetch, StoreManager.FORCE_LOAD_NONE))
return super.load(sm, fields, fetch, lockLevel, edata);
+ CacheStatistics stats = cache.getStatistics();
+ Class<?> cls = sm.getMetaData().getDescribedType();
DataCachePCData data = cache.get(sm.getObjectId());
if (lockLevel == LockLevels.LOCK_NONE && !isLocking(fetch) && data != null)
data.load(sm, fields, fetch, edata);
- if (fields.length() == 0)
+ if (fields.length() == 0){
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(cls, true);
+ }
return true;
+ }
// load from store manager; clone the set of still-unloaded fields
// so that if the store manager decides to modify it it won't affect us
@@ -452,15 +503,21 @@ public class DataCacheStoreManager
for (OpenJPAStateManager sm : smList) {
data = dataMap.get(sm.getObjectId());
-
+ CacheStatistics stats = cache.getStatistics();
if (sm.getManagedInstance() == null) {
if (data != null) {
//### the 'data.type' access here probably needs
//### to be addressed for bug 511
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), true);
+ }
sm.initialize(data.getType(), state);
data.load(sm, fetch, edata);
} else {
unloaded = addUnloaded(sm, null, unloaded);
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), false);
+ }
}
} else if (load != FORCE_LOAD_NONE
|| sm.getPCState() == PCState.HOLLOW) {
@@ -469,10 +526,22 @@ public class DataCacheStoreManager
// load unloaded fields
fields = sm.getUnloaded(fetch);
data.load(sm, fields, fetch, edata);
- if (fields.length() > 0)
+ if (fields.length() > 0){
unloaded = addUnloaded(sm, fields, unloaded);
- } else
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), false);
+ }
+ }else{
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), true);
+ }
+ }
+ } else{
unloaded = addUnloaded(sm, null, unloaded);
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newGet(sm.getMetaData().getDescribedType(), false);
+ }
+ }
}
}
}
@@ -517,6 +586,10 @@ public class DataCacheStoreManager
cache.put(data);
else
cache.update(data);
+ CacheStatistics stats = cache.getStatistics();
+ if (stats.isEnabled()) {
+ ((CacheStatisticsSPI)stats).newPut(sm.getMetaData().getDescribedType());
+ }
} finally {
cache.writeUnlock();
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java?rev=1004818&r1=1004817&r2=1004818&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/AbstractDataCacheInstrument.java Tue Oct 5 21:12:52 2010
@@ -218,46 +218,6 @@ public abstract class AbstractDataCacheI
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();
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java?rev=1004818&r1=1004817&r2=1004818&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/instrumentation/DataCacheInstrument.java Tue Oct 5 21:12:52 2010
@@ -60,17 +60,7 @@ public interface DataCacheInstrument {
*/
public long getTotalWriteCount(String className)
throws ClassNotFoundException;
-
- /**
- * Gets the number of cache evictions from the last reset.
- */
- public long getEvictionCount();
-
- /**
- * Gets the total number of cache evictions since cache start.
- */
- public long getTotalEvictionCount();
-
+
/**
* Returns the name of the cache
*/
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java?rev=1004818&r1=1004817&r2=1004818&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestStatistics.java Tue Oct 5 21:12:52 2010
@@ -18,129 +18,311 @@
*/
package org.apache.openjpa.persistence.datacache;
-import java.util.Arrays;
+import java.util.List;
import javax.persistence.EntityManager;
+import junit.framework.AssertionFailedError;
+
import org.apache.openjpa.datacache.CacheStatistics;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.StoreCache;
import org.apache.openjpa.persistence.StoreCacheImpl;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
/**
* Tests statistics of data cache operation.
- *
- * @author Pinaki Poddar
- *
+ *
*/
public class TestStatistics extends SingleEMFTestCase {
private static final boolean L2Cached = true;
private static final boolean L1Cached = true;
- private static CachedPerson person;
+ private static final Class<?> cls = CachedEntityStatistics.class;
+
+ Object[] p =
+ new Object[] { CLEAR_TABLES, CachedEntityStatistics.class
+ ,"openjpa.DataCache", "true(EnableStatistics=true)","openjpa.QueryCache", "true",
+// "openjpa.ConnectionFactoryProperties", "PrintParameters=True", "openjpa.Log","SQL=trace",
+ };
+
private EntityManager em;
private StoreCache cache;
CacheStatistics stats;
+
public void setUp() {
- super.setUp(CLEAR_TABLES, CachedPerson.class,
- "openjpa.DataCache", "true(EnableStatistics=true)",
- "openjpa.QueryCache", "true",
- "openjpa.RemoteCommitProvider", "sjvm");
+ super.setUp(p);
cache = emf.getStoreCache();
assertNotNull(cache);
stats = cache.getStatistics();
assertNotNull(stats);
em = emf.createEntityManager();
-
- person = createData();
+
stats.reset();
em.clear();
}
-
+
+ public void tearDown() throws Exception {
+
+ }
+
/**
* Test that the CacheStatistics is disabled by default.
*/
public void testDefaultSettings() {
- Object[] props = {"openjpa.DataCache", "true", "openjpa.RemoteCommitProvider", "sjvm"};
+ Object[] props = { "openjpa.DataCache", "true", "openjpa.RemoteCommitProvider", "sjvm" };
OpenJPAEntityManagerFactory emf1 = createNamedEMF("second-persistence-unit", props);
-
+
assertFalse(emf1.getStoreCache().getStatistics().isEnabled());
}
-
+
/**
* Finding an entity from a clean should hit the L2 cache.
*/
- public void testFind() {
+ public void testSimpleFind() {
+ int hit = 0, eviction = 0, read = 0, write = 0;
+ CachedEntityStatistics person = createData(false, false);
+ em.clear();
+ cache.getStatistics().reset();
assertTrue(cache.getStatistics().isEnabled());
Object pid = person.getId();
+ // Note -- the StoreCache interface doesn't calculate statistics
assertCached(person, pid, !L1Cached, L2Cached);
-
- long[] before = snapshot();
- CachedPerson p = em.find(CachedPerson.class, pid);
- long[] after = snapshot();
- assertDelta(before, after, 1, 1, 0); // READ:1 HIT:1, WRITE:0
+ CachedEntityStatistics p = em.find(CachedEntityStatistics.class, pid);
+ read++;
+ hit++;
+
+ assertion(cls, hit, read, write, stats);
+
+ em.find(CachedEntityStatistics.class, -1);
+ read++;
+
assertCached(p, pid, L1Cached, L2Cached);
+ }
+
+ public void testFind() {
+ int hit = 0, evict = 0, read = 0, write = 0;
+ CachedEntityStatistics person = createData(true, true);
+ em.clear();
+ cache.evictAll();
+ cache.getStatistics().reset();
+
+ // Make sure cache is enabled and empty
+ assertTrue(cache.getStatistics().isEnabled());
+ assertion(cls, hit, read, write, stats);
+
+ Object pid = person.getId();
+
+ // Should have 3 reads and 3 writes because of pid and it's eager relationship
+ CachedEntityStatistics p = em.find(CachedEntityStatistics.class, pid);
+ read++;
+ read++;
+ read++;
+ write++;
+ write++;
+ write++;
+ assertion(cls, hit, read, write, stats);
+
+ em.clear();
+ em.find(CachedEntityStatistics.class, person.getEagerList().toArray(new CachedEntityStatistics[0])[0].getId());
+ read++;
+ hit++;
+ em.clear();
+
+ // Should have two reads and two hits
+ person = em.find(CachedEntityStatistics.class, pid);
+ read++;
+ read++;
+ read++;
+ hit++;
+ hit++;
+ hit++;
+ assertion(cls, hit, read, write, stats);
+ em.clear();
+
+ // Evict 1 eager field data from cache
+ cache.evict(CachedEntityStatistics.class, person.getEagerList().toArray(new CachedEntityStatistics[0])[0]
+ .getId());
+ evict++;
+ p = em.find(CachedEntityStatistics.class, pid);
+ read++;
+ read++;
+ read++;
+ hit++;
+ hit++;
+ write++;
+
+ assertion(cls, hit, read, write, stats);
+
+ // Test lazy field -- should be a cache miss
+ assertEquals(1, p.getLazyList().size());
+ read++;
+ write++;
+ assertion(cls, hit, read, write, stats);
+ em.clear();
+
+ em.find(CachedEntityStatistics.class, p.getLazyList().toArray(new CachedEntityStatistics[0])[0].getId());
+ read++;
+ hit++;
+ assertion(cls, hit, read, write, stats);
}
-
+
public void testMultipleUnits() {
- String[] props = {"openjpa.DataCache", "true", "openjpa.RemoteCommitProvider", "sjvm"};
+ String[] props = { "openjpa.DataCache", "true", "openjpa.RemoteCommitProvider", "sjvm" };
OpenJPAEntityManagerFactory emf1 = createNamedEMF("test", props);
OpenJPAEntityManagerFactory emf2 = createNamedEMF("empty-pu", props);
assertNotSame(emf1, emf2);
assertNotSame(emf1.getStoreCache(), emf2.getStoreCache());
assertNotSame(emf1.getStoreCache().getStatistics(), emf2.getStoreCache().getStatistics());
- assertNotSame(((StoreCacheImpl)emf1.getStoreCache()).getDelegate(),
- ((StoreCacheImpl)emf2.getStoreCache()).getDelegate());
-
+ assertNotSame(((StoreCacheImpl) emf1.getStoreCache()).getDelegate(), ((StoreCacheImpl) emf2.getStoreCache())
+ .getDelegate());
+
}
-
- CachedPerson createData() {
+
+ public void testPersist() {
+ int hit = 0, evict = 0, read = 0, write = 0;
+
+ em = emf.createEntityManager();
+ // test single
em.getTransaction().begin();
- CachedPerson p = new CachedPerson();
- p.setId((int)System.currentTimeMillis());
+ em.persist(new CachedEntityStatistics());
+ write++;
+ em.getTransaction().commit();
+
+ assertion(cls, hit, read, write, stats);
+
+ // test multiple
+ CachedEntityStatistics root = new CachedEntityStatistics();
+ root.addEager(new CachedEntityStatistics());
+ root.addEager(new CachedEntityStatistics());
+ root.addLazy(new CachedEntityStatistics());
+ root.addLazy(new CachedEntityStatistics());
+ write += 5;
+ em.getTransaction().begin();
+ em.persist(root);
+ em.getTransaction().commit();
+ assertion(cls, hit, read, write, stats);
+
+ }
+
+ public void testRefresh() {
+ int hit = 0, evict = 0, read = 0, write = 0;
+ CachedEntityStatistics e = new CachedEntityStatistics();
+ em = emf.createEntityManager();
+ // test single
+ em.getTransaction().begin();
+ em.persist(e);
+ write++;
+ em.getTransaction().commit();
+ assertion(cls, hit, read, write, stats);
+
+ em.refresh(e);
+ read++;
+ assertion(cls, hit, read, write, stats);
+ em.clear();
+
+ }
+
+ public void testMerge() {
+ int hit = 0, evict = 0, read = 0, write = 0;
+ CachedEntityStatistics e = new CachedEntityStatistics();
+ em = emf.createEntityManager();
+ // test single
+ em.getTransaction().begin();
+ em.persist(e);
+ write++;
+ em.getTransaction().commit();
+ assertion(cls, hit, read, write, stats);
+ em.clear();
+ cache.evictAll();
+
+ em.getTransaction().begin();
+ em.merge(e);
+
+ em.getTransaction().commit();
+ // TODO -- BROKEN
+ // DataCacheStoreManager.flush(...) doesn't account for some of this traffic.
+ // read++;
+ assertion(cls, hit, read, write, stats);
+
+ }
+
+ CachedEntityStatistics createData(boolean lazy, boolean eager) {
+ List<CachedEntityStatistics> eagerList = null;
+ List<CachedEntityStatistics> lazyList = null;
+
+ em.getTransaction().begin();
+ CachedEntityStatistics p = new CachedEntityStatistics();
+ if (lazy) {
+ p.addLazy(new CachedEntityStatistics());
+ }
+ if (eager) {
+ p.addEager(new CachedEntityStatistics());
+ p.addEager(new CachedEntityStatistics());
+ }
em.persist(p);
+
em.getTransaction().commit();
return p;
}
-
+
/**
* Get {hit,read,write} count for the cache across all instances.
*/
long[] snapshot() {
- return new long[]{stats.getReadCount(), stats.getHitCount(), stats.getWriteCount()};
+ return new long[] { stats.getReadCount(), stats.getHitCount(), stats.getWriteCount() };
}
-
+
/**
* Get {hit,read,write} count for the cache across given class extent.
*/
long[] snapshot(Class<?> cls) {
- return new long[]{stats.getReadCount(cls), stats.getHitCount(cls), stats.getWriteCount(cls)};
+ return new long[] { stats.getReadCount(cls), stats.getHitCount(cls), stats.getWriteCount(cls) };
}
-
+
+ /**
+ * Assert that the passed in hit/eviction/read/write match those values collected by stats.
+ */
+ private static final void assertion(Class<?> cls, int hit, int read, int write, CacheStatistics stats) {
+ if (cls == null) {
+ throw new RuntimeException("invalid assertion. Null class");
+ } else {
+ try {
+ assertEquals("Hit count doesn't match", hit, stats.getHitCount(cls));
+ assertEquals("Read count doesn't match", read, stats.getReadCount(cls));
+ assertEquals("Write count doesn't match", write, stats.getWriteCount(cls));
+ } catch (AssertionFailedError t) {
+ System.out.println("hit : " + stats.getHitCount(cls) + " read: " + stats.getReadCount(cls) + " write: "
+ + stats.getWriteCount(cls));
+ throw t;
+ }
+ }
+
+ }
+
void assertDelta(long[] before, long[] after, long readDelta, long hitDelta, long writeDelta) {
- assertEquals("READ count mismatch", readDelta, after[0] - before[0]);
- assertEquals("HIT count mismatch", hitDelta, after[1] - before[1]);
+ assertEquals("READ count mismatch", readDelta, after[0] - before[0]);
+ assertEquals("HIT count mismatch", hitDelta, after[1] - before[1]);
assertEquals("WRITE count mismatch", writeDelta, after[2] - before[2]);
}
-
-
+
void assertCached(Object o, Object oid, boolean l1, boolean l2) {
boolean l1a = em.contains(o);
boolean l2a = cache.contains(o.getClass(), oid);
if (l1 != l1a) {
- fail("Expected " + (l1 ? "":"not") + " to find instance " +
- o.getClass().getSimpleName()+":"+oid + " in L1 cache");
+ fail("Expected " + (l1 ? "" : "not") + " to find instance " + o.getClass().getSimpleName() + ":" + oid
+ + " in L1 cache");
}
if (l2 != l2a) {
- fail("Expected " + (l2 ? "":"not") + " to find instance " +
- o.getClass().getSimpleName()+":"+oid + " in L2 cache");
+ fail("Expected " + (l2 ? "" : "not") + " to find instance " + o.getClass().getSimpleName() + ":" + oid
+ + " in L2 cache");
}
}
-
+
void print(String msg, CacheStatistics stats) {
- System.err.println(msg + stats + " H:" + stats.getHitCount() + " R:" + stats.getReadCount() + " W:" +
- stats.getWriteCount());
+ System.err.println(msg + stats + " H:" + stats.getHitCount() + " R:" + stats.getReadCount() + " W:"
+ + stats.getWriteCount());
}
}