[jboss-cvs] JBossCache/src/org/jboss/cache ...
Manik Surtani
msurtani at jboss.com
Tue Nov 28 22:20:53 EST 2006
User: msurtani
Date: 06/11/28 22:20:53
Modified: src/org/jboss/cache Tag: Branch_JBossCache_1_3_0
TreeCache.java
Log:
fixed more bugs
Revision Changes Path
No revision
No revision
1.142.2.4 +127 -54 JBossCache/src/org/jboss/cache/TreeCache.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TreeCache.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TreeCache.java,v
retrieving revision 1.142.2.3
retrieving revision 1.142.2.4
diff -u -b -r1.142.2.3 -r1.142.2.4
--- TreeCache.java 24 Nov 2006 14:19:30 -0000 1.142.2.3
+++ TreeCache.java 29 Nov 2006 03:20:53 -0000 1.142.2.4
@@ -7,7 +7,6 @@
package org.jboss.cache;
import EDU.oswego.cs.dl.util.concurrent.CopyOnWriteArraySet;
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.config.CacheLoaderConfig;
@@ -61,7 +60,7 @@
* @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
* @author Brian Stansberry
* @author Daniel Huang (dhuang at jboss.org)
- * @version $Id: TreeCache.java,v 1.142.2.3 2006/11/24 14:19:30 msurtani Exp $
+ * @version $Id: TreeCache.java,v 1.142.2.4 2006/11/29 03:20:53 msurtani Exp $
* <p/>
*/
public class TreeCache extends ServiceMBeanSupport implements TreeCacheMBean, Cloneable, MembershipListener
@@ -109,6 +108,7 @@
protected Map region_msg_queues = new HashMap();
protected boolean use_interceptor_mbeans = true;
+ private static final String REMOVAL_MARKER = "__JBOSS_MARKED_FOR_REMOVAL";
/**
* Maintains mapping of transactions (keys) and Modifications/Undo-Operations
*/
@@ -301,7 +301,7 @@
*/
protected final Set activationChangeNodes = new HashSet();
- private Map removedNodes = new ConcurrentHashMap();
+// private Map removedNodes = new ConcurrentHashMap();
static
{
@@ -1135,10 +1135,10 @@
return this;
}
- public Map getRemovedNodesMap()
- {
- return removedNodes;
- }
+// public Map getRemovedNodesMap()
+// {
+// return removedNodes;
+// }
/**
* Fetch the group state from the current coordinator. If successful, this will trigger setState().
@@ -3069,12 +3069,12 @@
//added so I can get nodes internally without triggering stuff
public DataNode peek(Fqn fqn)
{
- DataNode n = findInternal(fqn);
- if (n == null)
- {
- // check the deleted nodes map
- n = (DataNode) removedNodes.get(fqn);
- }
+ DataNode n = findInternal(fqn, true);
+// if (n == null)
+// {
+// // check the deleted nodes map
+// n = (DataNode) removedNodes.get(fqn);
+// }
return n;
}
@@ -3098,7 +3098,7 @@
*/
public boolean exists(Fqn fqn)
{
- DataNode n = findInternal(fqn);
+ DataNode n = findInternal(fqn, false);
return n != null;
}
@@ -3107,7 +3107,7 @@
*
* @param fqn
*/
- private DataNode findInternal(Fqn fqn)
+ private DataNode findInternal(Fqn fqn, boolean includeNodesMarkedAsRemoved)
{
if (fqn == null || fqn.size() == 0) return root;
TreeNode n = root, retval = null;
@@ -3119,6 +3119,8 @@
n = n.getChild(obj);
if (n == null)
return null;
+ else if (!includeNodesMarkedAsRemoved && isMarkedForRemoval(n))
+ return null;
else
retval = n;
}
@@ -3146,7 +3148,7 @@
*/
public boolean exists(Fqn fqn, Object key)
{
- DataNode n = findInternal(fqn);
+ DataNode n = findInternal(fqn, false);
if (n == null)
return false;
else
@@ -3586,18 +3588,18 @@
}
} else
sb.append(SEPARATOR);
- if (!removedNodes.isEmpty())
- {
- sb.append("\n\nPlus the following locks on removed nodes:\n");
- for (Iterator it = removedNodes.keySet().iterator(); it.hasNext();)
- {
- Fqn f = (Fqn) it.next();
- DataNode dn = (DataNode) removedNodes.get(f);
- sb.append(" ");
- sb.append(f);
- dn.printLockInfo(sb, indent);
- }
- }
+// if (!removedNodes.isEmpty())
+// {
+// sb.append("\n\nPlus the following locks on removed nodes:\n");
+// for (Iterator it = removedNodes.keySet().iterator(); it.hasNext();)
+// {
+// Fqn f = (Fqn) it.next();
+// DataNode dn = (DataNode) removedNodes.get(f);
+// sb.append(" ");
+// sb.append(f);
+// dn.printLockInfo(sb, indent);
+// }
+// }
return sb.toString();
}
@@ -3606,7 +3608,7 @@
*/
public int getNumberOfLocksHeld()
{
- return numLocks(root) + removedNodes.size();
+ return numLocks(root);// + removedNodes.size();
}
@@ -3905,9 +3907,7 @@
log.trace(new StringBuffer("_put(").append(tx).append(", \"").append(fqn).append("\", ").append(data).append(")"));
}
- // Find the node. This will lock it (if <tt>locking</tt> is true) and
- // add the temporarily created parent nodes to the TX's node list if tx != null)
- n = findNode(fqn);
+ n = findInternal(fqn, true);
if (n == null)
{
String errStr = "node " + fqn + " not found (gtx=" + tx + ", caller=" + Thread.currentThread() + ")";
@@ -3916,6 +3916,9 @@
throw new NodeNotExistsException(errStr);
}
notifyNodeModify(fqn, true);
+
+ scrubRemoveMarker(n, false);
+
// TODO: move creation of undo-operations to separate Interceptor
// create a compensating method call (reverting the effect of
// this modification) and put it into the TX's undo list.
@@ -3980,7 +3983,7 @@
append(fqn).append("\", ").append(key).append(", ").append(value).append(")"));
}
- n = findNode(fqn);
+ n = findInternal(fqn, true);
if (n == null)
{
String errStr = "node " + fqn + " not found (gtx=" + tx + ", caller=" + Thread.currentThread() + ")";
@@ -3993,6 +3996,8 @@
old_value = n.get(key);
n.put(key, value);
+ scrubRemoveMarker(n, false);
+
// create a compensating method call (reverting the effect of
// this modification) and put it into the TX's undo list.
if (tx != null && create_undo_ops)
@@ -4074,6 +4079,26 @@
throws CacheException
{
+ // check if this is triggered by a rollback operation ...
+ if (tx != null)
+ {
+ try
+ {
+ int status = getTransactionManager().getTransaction().getStatus();
+ if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK)
+ {
+ if (log.isDebugEnabled()) log.debug("This remove call is triggered by a transaction rollback, as a compensation operation. Do a realRemove() instead.");
+ realRemove(fqn, true);
+ return;
+ }
+ }
+ catch (Exception e)
+ {
+ // what do we do here?
+ log.trace("Caught exception dealing with transaction manager", e);
+ }
+ }
+
DataNode n;
TreeNode parent_node;
MethodCall undo_op = null;
@@ -4121,7 +4146,13 @@
parent_node = n.getParent();
// remove subtree from parent
+ // parent_node.removeChild(n.getName());
+ // don't actually remove the node if pessimistically locked - just mark the node for removal
+ if (isNodeLockingOptimistic())
parent_node.removeChild(n.getName());
+ else
+ markForRemoval(n);
+
if (eviction)
parent_node.setChildrenLoaded(false);
@@ -4150,6 +4181,65 @@
}
}
+ private void markForRemoval(TreeNode n)
+ {
+ n.put(REMOVAL_MARKER, null);
+ // mark children as well.
+ Map children = n.getChildren();
+ if (children != null && !children.isEmpty())
+ {
+ // traverse children
+ Iterator i = children.values().iterator();
+ while (i.hasNext())
+ {
+ markForRemoval((TreeNode) i.next());
+ }
+ }
+ }
+
+ private void scrubRemoveMarker(TreeNode n, boolean deep)
+ {
+ n.remove(REMOVAL_MARKER);
+ // unmark children as well.
+ Map children = n.getChildren();
+ if (children != null && !children.isEmpty())
+ {
+ // traverse children
+ Iterator i = children.values().iterator();
+ while (i.hasNext())
+ {
+ scrubRemoveMarker((TreeNode) i.next(), true);
+ }
+ }
+
+ }
+
+ private boolean isMarkedForRemoval(TreeNode n)
+ {
+ return n.containsKey(REMOVAL_MARKER);
+ }
+
+ /**
+ * Internal method; not to be used externally.
+ * @param f
+ */
+ public void realRemove(Fqn f, boolean skipMarkerCheck)
+ {
+ DataNode n = findInternal(f, true);
+ if (n == null)
+ return;
+
+ if (log.isDebugEnabled()) log.debug("Performing a real remove for node " + f + ", marked for removal.");
+ if (skipMarkerCheck || isMarkedForRemoval(n))
+ {
+ n.getParent().removeChild(n.getName());
+ }
+ else
+ {
+ if (log.isDebugEnabled()) log.debug("Node " + f + " NOT marked for removal as expected, not removing!");
+ }
+ }
+
/**
* @param fqn
* @param key
@@ -4388,6 +4478,8 @@
return;
}
tmp.addChild(child_name, old_node);
+ // make sure any deleted markers are removed from this child.
+ scrubRemoveMarker(old_node, true);
notifyNodeCreated(new Fqn(parent_fqn, child_name));
}
@@ -4930,26 +5022,7 @@
int treeNodeSize;
if (fqn == null) return null;
- DataNode toReturn = null;
- if ((treeNodeSize = fqn.size()) == 0)
- {
- toReturn = root;
- } else
- {
- n = root;
- for (int i = 0; i < treeNodeSize; i++)
- {
- child_name = fqn.get(i);
- child_node = n.getChild(child_name);
- if (child_node == null)
- {
- toReturn = null;
- break;
- }
- n = child_node;
- }
- toReturn = (DataNode) child_node;
- }
+ DataNode toReturn = findInternal(fqn, false);
if (version != null)
{
More information about the jboss-cvs-commits
mailing list