[jboss-cvs] JBossCache/src/org/jboss/cache/interceptors ...
Manik Surtani
msurtani at jboss.com
Mon Sep 4 17:06:18 EDT 2006
User: msurtani
Date: 06/09/04 17:06:18
Modified: src/org/jboss/cache/interceptors
ActivationInterceptor.java
CacheLoaderInterceptor.java
Log:
Fixed passivation bugs
Revision Changes Path
1.34 +151 -99 JBossCache/src/org/jboss/cache/interceptors/ActivationInterceptor.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: ActivationInterceptor.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/ActivationInterceptor.java,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- ActivationInterceptor.java 25 Aug 2006 14:10:07 -0000 1.33
+++ ActivationInterceptor.java 4 Sep 2006 21:06:18 -0000 1.34
@@ -9,8 +9,8 @@
import org.jboss.cache.TransactionTable;
import org.jboss.cache.TreeCache;
import org.jboss.cache.TreeCacheProxyImpl;
-import org.jboss.cache.marshall.MethodDeclarations;
import org.jboss.cache.marshall.MethodCall;
+import org.jboss.cache.marshall.MethodDeclarations;
import javax.transaction.TransactionManager;
import java.lang.reflect.Method;
@@ -27,21 +27,26 @@
* their attributes have been initialized and their children have been loaded in memory.
*
* @author <a href="mailto:{hmesha at novell.com}">{Hany Mesha}</a>
- * @version $Id: ActivationInterceptor.java,v 1.33 2006/08/25 14:10:07 msurtani Exp $
+ * @version $Id: ActivationInterceptor.java,v 1.34 2006/09/04 21:06:18 msurtani Exp $
*/
-public class ActivationInterceptor extends CacheLoaderInterceptor implements ActivationInterceptorMBean {
+public class ActivationInterceptor extends CacheLoaderInterceptor implements ActivationInterceptorMBean
+{
- protected TransactionManager tx_mgr=null;
- protected TransactionTable tx_table=null;
+ protected TransactionManager tx_mgr = null;
+ protected TransactionTable tx_table = null;
private HashMap m_txActivations = new HashMap();
private long m_activations = 0;
- /** List<Transaction> that we have registered for */
- protected ConcurrentHashMap transactions=new ConcurrentHashMap(16);
- protected static final Object NULL=new Object();
+ /**
+ * List<Transaction> that we have registered for
+ */
+ protected ConcurrentHashMap transactions = new ConcurrentHashMap(16);
+ protected static final Object NULL = new Object();
- public ActivationInterceptor() {
+ public ActivationInterceptor()
+ {
this.useCacheStore = false;
+ isActivation = true;
}
/**
@@ -52,10 +57,11 @@
* @return
* @throws Throwable
*/
- public Object invoke(MethodCall m) throws Throwable {
+ public Object invoke(MethodCall m) throws Throwable
+ {
- Fqn fqn=null;
- Object[] args=m.getArgs();
+ Fqn fqn = null;
+ Object[] args = m.getArgs();
Object retval;
// First call the parent class to load the node
@@ -65,27 +71,35 @@
boolean nodeRemoved = false;
// Could be TRANSACTIONAL. If so, we register for TX completion (if we haven't done so yet)
- if(tx_mgr != null && tx_mgr.getTransaction() != null) {
+ if (tx_mgr != null && tx_mgr.getTransaction() != null)
+ {
GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction();
switch (m.getMethodId())
{
case MethodDeclarations.commitMethod_id:
- if (hasModifications(args)) {
+ if (hasModifications(args))
+ {
loader.commit(gtx);
- if (configuration.isUseInterceptorMbeans() && getStatisticsEnabled()) {
- Integer acts = (Integer)m_txActivations.get(gtx);
+ if (configuration.isUseInterceptorMbeans() && getStatisticsEnabled())
+ {
+ Integer acts = (Integer) m_txActivations.get(gtx);
if (acts != null)
+ {
m_activations = m_activations + acts.intValue();
+ }
m_txActivations.remove(gtx);
}
}
break;
case MethodDeclarations.rollbackMethod_id:
- if (hasModifications(args)) {
+ if (hasModifications(args))
+ {
loader.rollback(gtx);
if (configuration.isUseInterceptorMbeans() && getStatisticsEnabled())
+ {
m_txActivations.remove(gtx);
}
+ }
break;
case MethodDeclarations.optimisticPrepareMethod_id:
case MethodDeclarations.prepareMethod_id:
@@ -103,54 +117,63 @@
case MethodDeclarations.putDataMethodLocal_id:
case MethodDeclarations.putDataEraseMethodLocal_id:
case MethodDeclarations.putKeyValMethodLocal_id:
- fqn=(Fqn)args[1];
+ fqn = (Fqn) args[1];
break;
case MethodDeclarations.removeKeyMethodLocal_id:
case MethodDeclarations.removeDataMethodLocal_id:
- fqn=(Fqn)args[1];
+ fqn = (Fqn) args[1];
break;
case MethodDeclarations.addChildMethodLocal_id:
- fqn=(Fqn)args[1];
+ fqn = (Fqn) args[1];
break;
case MethodDeclarations.getKeyValueMethodLocal_id:
- fqn=(Fqn)args[0];
+ fqn = (Fqn) args[0];
break;
case MethodDeclarations.getNodeMethodLocal_id:
- fqn=(Fqn)args[0];
+ fqn = (Fqn) args[0];
break;
case MethodDeclarations.getKeysMethodLocal_id:
- fqn=(Fqn)args[0];
+ fqn = (Fqn) args[0];
break;
case MethodDeclarations.getChildrenNamesMethodLocal_id:
case MethodDeclarations.releaseAllLocksMethodLocal_id:
case MethodDeclarations.printMethodLocal_id:
- fqn=(Fqn)args[0];
+ fqn = (Fqn) args[0];
break;
case MethodDeclarations.removeNodeMethodLocal_id:
nodeRemoved = true;
- fqn=(Fqn)args[1];
+ fqn = (Fqn) args[1];
break;
}
- synchronized(this) {
+ synchronized (this)
+ {
if (fqn != null && nodeRemoved)
// If the node is being removed, just remove it and don't perform
// activation processing
+ {
loader.remove(fqn);
- else if (fqn != null && cache.hasChild(fqn) && loader.exists(fqn)) {
+ }
+ else if (fqn != null && cache.hasChild(fqn) && loader.exists(fqn))
+ {
// Remove the node from the cache loader if it exists in memory,
// its attributes have been initialized, its children have been loaded,
// AND it was found in the cache loader (nodeLoaded = true).
// Then notify the listeners that the node has been activated.
Node n = getNode(fqn); // don't load
// node not null and attributes have been loaded?
- if (n != null && !n.getKeys().contains(TreeCache.UNINITIALIZED)) {
- if (!n.getChildren().isEmpty()) {
- if (allInitialized(n)) {
+ if (n != null && !n.getKeys().contains(TreeCache.UNINITIALIZED))
+ {
+ if (!n.getChildren().isEmpty())
+ {
+ if (allInitialized(n))
+ {
log.debug("children all initialized");
remove(fqn);
}
- } else if (loaderNoChildren(fqn)) {
+ }
+ else if (loaderNoChildren(fqn))
+ {
log.debug("no children " + n);
remove(fqn);
}
@@ -160,18 +183,22 @@
return retval;
}
- private void remove(Fqn fqn) throws Exception {
+ private void remove(Fqn fqn) throws Exception
+ {
cache.getNotifier().notifyNodeActivated(fqn, true);
loader.remove(fqn);
if (configuration.isUseInterceptorMbeans() && getStatisticsEnabled())
+ {
m_activations++;
}
+ }
/**
* Returns true if a node has all children loaded and initialized.
*/
- private boolean allInitialized(Node n) {
- if (!((TreeCacheProxyImpl)n).getChildrenLoaded()) return false;
+ private boolean allInitialized(Node n)
+ {
+ if (!((TreeCacheProxyImpl) n).getChildrenLoaded()) return false;
for (Node child : n.getChildren())
{
@@ -186,66 +213,83 @@
*/
private boolean loaderNoChildren(Fqn fqn)
{
- try {
+ try
+ {
Set children_names = loader.getChildrenNames(fqn);
return (children_names == null);
}
- catch (Exception e) {
+ catch (Exception e)
+ {
log.error("failed getting the children names for " + fqn + " from the cache loader", e);
return false;
}
}
- public long getActivations() {
+ public long getActivations()
+ {
return m_activations;
}
- public void resetStatistics() {
+ public void resetStatistics()
+ {
super.resetStatistics();
m_activations = 0;
}
- public Map dumpStatistics() {
+ public Map dumpStatistics()
+ {
Map retval = super.dumpStatistics();
if (retval == null)
+ {
retval = new HashMap();
+ }
retval.put("Activations", new Long(m_activations));
return retval;
}
- protected boolean hasModifications(Object[] args) {
+ protected boolean hasModifications(Object[] args)
+ {
int hint = 1;
if (args[hint] instanceof Boolean) return ((Boolean) args[hint]).booleanValue();
- for (int i = 0; i < args.length; i++) {
+ for (int i = 0; i < args.length; i++)
+ {
if (args[i] instanceof Boolean) return ((Boolean) args[i]).booleanValue();
}
return false;
}
- private void prepareCacheLoader(GlobalTransaction gtx) throws Exception {
+ private void prepareCacheLoader(GlobalTransaction gtx) throws Exception
+ {
List modifications;
TransactionEntry entry;
int txActs = 0;
- entry=tx_table.get(gtx);
- if(entry == null)
+ entry = tx_table.get(gtx);
+ if (entry == null)
+ {
throw new Exception("entry for transaction " + gtx + " not found in transaction table");
- modifications=entry.getCacheLoaderModifications();
- if(modifications.size() == 0)
+ }
+ modifications = entry.getCacheLoaderModifications();
+ if (modifications.size() == 0)
+ {
return;
- List cache_loader_modifications=new ArrayList();
- for(Iterator it=modifications.iterator(); it.hasNext();) {
- MethodCall methodCall=(MethodCall)it.next();
- Method method=methodCall.getMethod();
+ }
+ List cache_loader_modifications = new ArrayList();
+ for (Iterator it = modifications.iterator(); it.hasNext();)
+ {
+ MethodCall methodCall = (MethodCall) it.next();
+ Method method = methodCall.getMethod();
Object[] args;
- if(method == null)
+ if (method == null)
+ {
throw new Exception("method call has no method: " + methodCall);
- args=methodCall.getArgs();
+ }
+ args = methodCall.getArgs();
switch (methodCall.getMethodId())
{
case MethodDeclarations.removeNodeMethodLocal_id:
// just remove it from loader, don't trigger activation processing
- Modification mod=new Modification(Modification.REMOVE_NODE, (Fqn)args[1]);
+ Modification mod = new Modification(Modification.REMOVE_NODE, (Fqn) args[1]);
cache_loader_modifications.add(mod);
break;
case MethodDeclarations.putDataMethodLocal_id:
@@ -256,19 +300,23 @@
// been initialized, its children have been loaded
// AND it was found in the cache loader (nodeLoaded = true).
// Then notify the listeners that the node has been activated.
- Fqn fqn = (Fqn)args[1];
- if(fqn != null && cache.hasChild(fqn) && loader.exists(fqn)) {
- Node n=getNode(fqn); // don't load
+ Fqn fqn = (Fqn) args[1];
+ if (fqn != null && cache.hasChild(fqn) && loader.exists(fqn))
+ {
+ Node n = getNode(fqn); // don't load
// node not null and attributes have been loaded?
- if (n != null && !n.getKeys().contains(TreeCache.UNINITIALIZED)) {
+ if (n != null && !n.getKeys().contains(TreeCache.UNINITIALIZED))
+ {
// has children?
- if(!n.getChildren().isEmpty() && allInitialized(n)) {
+ if (!n.getChildren().isEmpty() && allInitialized(n))
+ {
// children have been loaded, remove the node
addRemoveMod(cache_loader_modifications, fqn);
txActs++;
}
// doesn't have children, check the cache loader
- else if (loaderNoChildren(fqn)) {
+ else if (loaderNoChildren(fqn))
+ {
addRemoveMod(cache_loader_modifications, fqn);
txActs++;
}
@@ -277,14 +325,18 @@
break;
}
}
- if (cache_loader_modifications.size() > 0) {
+ if (cache_loader_modifications.size() > 0)
+ {
loader.prepare(gtx, cache_loader_modifications, false);
if (configuration.isUseInterceptorMbeans() && getStatisticsEnabled() && txActs > 0)
+ {
m_txActivations.put(gtx, new Integer(txActs));
}
}
+ }
- private void addRemoveMod(List l, Fqn fqn) {
+ private void addRemoveMod(List l, Fqn fqn)
+ {
Modification mod = new Modification(Modification.REMOVE_NODE, fqn);
l.add(mod);
cache.getNotifier().notifyNodeActivated(fqn, false);
1.51 +43 -4 JBossCache/src/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: CacheLoaderInterceptor.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/CacheLoaderInterceptor.java,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- CacheLoaderInterceptor.java 30 Aug 2006 20:28:15 -0000 1.50
+++ CacheLoaderInterceptor.java 4 Sep 2006 21:06:18 -0000 1.51
@@ -32,7 +32,7 @@
* Loads nodes that don't exist at the time of the call into memory from the CacheLoader
*
* @author Bela Ban
- * @version $Id: CacheLoaderInterceptor.java,v 1.50 2006/08/30 20:28:15 msurtani Exp $
+ * @version $Id: CacheLoaderInterceptor.java,v 1.51 2006/09/04 21:06:18 msurtani Exp $
*/
public class CacheLoaderInterceptor extends BaseCacheLoaderInterceptor implements CacheLoaderInterceptorMBean
{
@@ -40,6 +40,7 @@
private long m_cacheLoads = 0;
private long m_cacheMisses = 0;
private TransactionTable txTable = null;
+ protected boolean isActivation = false;
/**
* True if CacheStoreInterceptor is in place.
@@ -110,7 +111,9 @@
}
if (log.isTraceEnabled())
+ {
log.trace("invoke " + m);
+ }
switch (m.getMethodId())
{
case MethodDeclarations.putDataEraseMethodLocal_id:
@@ -121,9 +124,13 @@
case MethodDeclarations.putKeyValMethodLocal_id:
fqn = (Fqn) args[1];
if (useCacheStore)
+ {
initNode = true;
+ }
else
+ {
acquireLock = true;
+ }
break;
case MethodDeclarations.addChildMethodLocal_id:
fqn = (Fqn) args[1];
@@ -176,13 +183,19 @@
boolean mustLoad = mustLoad(n, key);
if (log.isTraceEnabled())
+ {
log.trace("load element " + fqn + " mustLoad=" + mustLoad);
+ }
if (mustLoad)
{
if (initNode)
+ {
n = createTempNode(fqn, entry);
+ }
else if (!wasRemovedInTx(fqn))
+ {
n = loadNode(fqn, n, entry);
+ }
// Only attempt to acquire this lock if we need to - i.e., if
// the lock hasn't already been acquired by the Lock
// interceptor. CRUD methods (put, remove) would have acquired
@@ -196,8 +209,10 @@
// org.jboss.cache.loader.deadlock.ConcurrentCreationDeadlockTest
// - Manik Surtani (21 March 2006)
if (acquireLock)
+ {
lock(fqn, DataNode.LockType.WRITE, false); // not recursive
}
+ }
// The complete list of children aren't known without loading them
if (m.getMethodId() == MethodDeclarations.getChildrenNamesMethodLocal_id)
@@ -227,11 +242,15 @@
TreeCacheProxyImpl n = (TreeCacheProxyImpl) node;
if (n != null && n.getChildrenLoaded())
+ {
return;
+ }
Set children_names = loader.getChildrenNames(fqn);
if (log.isTraceEnabled())
+ {
log.trace("load children " + fqn + " children=" + children_names);
+ }
// For getChildrenNames null means no children
if (children_names == null)
@@ -239,7 +258,9 @@
if (n != null)
{
if (useCacheStore)
+ {
n.setChildren(null);
+ }
n.setChildrenLoaded(true);
}
return;
@@ -333,7 +354,9 @@
{
GlobalTransaction t = cache.getInvocationContext().getGlobalTransaction();
if (t == null)
+ {
return false;
+ }
TransactionEntry entry = txTable.get(t);
Iterator i = entry.getCacheLoaderModifications().iterator();
while (i.hasNext())
@@ -341,8 +364,10 @@
MethodCall m = (MethodCall) i.next();
if (m.getMethodId() == MethodDeclarations.removeNodeMethodLocal_id
&& fqn.isChildOrEquals((Fqn) m.getArgs()[1]))
+ {
return true;
}
+ }
return false;
}
@@ -380,7 +405,9 @@
cache.getInvocationContext().getOptionOverrides().setBypassInterceptorChain(true);
n.put(TreeCache.UNINITIALIZED, null);
if (log.isTraceEnabled())
+ {
log.trace("createTempNode n " + n);
+ }
return n;
}
@@ -477,10 +504,14 @@
if (configuration.isUseInterceptorMbeans() && getStatisticsEnabled())
{
if (nodeExists)
+ {
m_cacheLoads++;
+ }
else
+ {
m_cacheMisses++;
}
+ }
if (!nodeExists && isCustomCacheLoader)
{
@@ -489,9 +520,17 @@
if (nodeExists)
{
+ if (isActivation)
+ {
+ cache.getNotifier().notifyNodeActivated(fqn, true);
+ cache.getNotifier().notifyNodeActivated(fqn, false);
+ }
+ else
+ {
cache.getNotifier().notifyNodeLoaded(fqn, true, Collections.emptyMap());
cache.getNotifier().notifyNodeLoaded(fqn, false, nodeData);
}
+ }
return nodeData;
}
More information about the jboss-cvs-commits
mailing list