[jboss-cvs] JBossCache/src/org/jboss/cache ...
Manik Surtani
msurtani at jboss.com
Mon Dec 4 19:01:52 EST 2006
User: msurtani
Date: 06/12/04 19:01:52
Modified: src/org/jboss/cache Tag: Branch_JBossCache_1_4_0
TransactionEntry.java TreeCache.java
TransactionTable.java
Log:
ported fixes for JBCACHE-871 and JBCACHE-875 from the 1.3.0 branch
Revision Changes Path
No revision
No revision
1.8.2.1 +33 -6 JBossCache/src/org/jboss/cache/TransactionEntry.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TransactionEntry.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TransactionEntry.java,v
retrieving revision 1.8
retrieving revision 1.8.2.1
diff -u -b -r1.8 -r1.8.2.1
--- TransactionEntry.java 12 Jun 2006 20:24:32 -0000 1.8
+++ TransactionEntry.java 5 Dec 2006 00:01:51 -0000 1.8.2.1
@@ -7,15 +7,19 @@
package org.jboss.cache;
-import org.jboss.cache.lock.IdentityLock;
-import org.jboss.cache.config.Option;
-import org.jgroups.blocks.MethodCall;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.lock.IdentityLock;
+import org.jgroups.blocks.MethodCall;
import javax.transaction.Transaction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
/**
* This is the value (key being the {@link GlobalTransaction}) in the transaction table
@@ -31,7 +35,7 @@
* </ul>
*
* @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 14, 2003
- * @version $Revision: 1.8 $
+ * @version $Revision: 1.8.2.1 $
*/
public class TransactionEntry {
@@ -69,6 +73,11 @@
protected List dummyNodesCreatedByCacheLoader;
/**
+ * List<Fqn> of nodes that have been removed by the transaction
+ */
+ protected List removedNodes = new LinkedList();
+
+ /**
* Constructs a new TransactionEntry.
*/
public TransactionEntry() {
@@ -109,6 +118,24 @@
}
/**
+ * Adds the node that has been removed.
+ *
+ * @param fqn
+ */
+ public void addRemovedNode(Fqn fqn) {
+ removedNodes.add(fqn);
+ }
+
+ /**
+ * Gets the list of removed nodes.
+ */
+ public List getRemovedNodes()
+ {
+ return new ArrayList(removedNodes);
+ }
+
+
+ /**
* Returns the undo operations in use.
* Note: This list may be concurrently modified.
*/
1.195.2.26 +125 -34 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.195.2.25
retrieving revision 1.195.2.26
diff -u -b -r1.195.2.25 -r1.195.2.26
--- TreeCache.java 4 Dec 2006 17:00:06 -0000 1.195.2.25
+++ TreeCache.java 5 Dec 2006 00:01:51 -0000 1.195.2.26
@@ -99,7 +99,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.195.2.25 2006/12/04 17:00:06 bstansberry Exp $
+ * @version $Id: TreeCache.java,v 1.195.2.26 2006/12/05 00:01:51 msurtani Exp $
* <p/>
* @see <a href="http://labs.jboss.com/portal/jbosscache/docs">JBossCache doc</a>
*/
@@ -108,6 +108,8 @@
private static final String CREATE_MUX_CHANNEL = "createMultiplexerChannel";
private static final String[] MUX_TYPES = {"java.lang.String", "java.lang.String"};
private static final String JBOSS_SERVER_DOMAIN = "jboss";
+
+ private static final String REMOVAL_MARKER = "__JBOSS_MARKED_FOR_REMOVAL";
/**
* Default replication version, from {@link Version#getVersionShort}.
*/
@@ -3566,7 +3568,7 @@
*/
public DataNode peek(Fqn fqn)
{
- return findInternal(fqn);
+ return findInternal(fqn, true);
}
/**
@@ -3595,7 +3597,7 @@
*/
public boolean exists(Fqn fqn)
{
- DataNode n = findInternal(fqn);
+ DataNode n = findInternal(fqn, false);
return n != null;
}
@@ -3604,7 +3606,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;
@@ -3615,6 +3617,8 @@
n = n.getChild(obj);
if (n == null)
return null;
+ else if (!includeNodesMarkedAsRemoved && isMarkedForRemoval(n))
+ return null;
}
return (DataNode) n;
}
@@ -3640,11 +3644,8 @@
*/
public boolean exists(Fqn fqn, Object key)
{
- DataNode n = findInternal(fqn);
- if (n == null)
- return false;
- else
- return n.containsKey(key);
+ DataNode n = findInternal(fqn, false);
+ return n != null && n.containsKey(key);
}
@@ -4055,6 +4056,14 @@
int indent = 0;
Map children;
+ sb.append("Root lock: ");
+ if(root.isLocked()) {
+ sb.append("\t(");
+ root.getLock().toString(sb);
+ sb.append(")");
+ }
+ sb.append("\n");
+
children = root.getChildren();
if (children != null && children.size() > 0)
{
@@ -4127,6 +4136,76 @@
return count;
}
+ 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))
+ {
+ if (n.getFqn().isRoot())
+ {
+ // do not actually delete; just remove deletion marker
+ scrubRemoveMarker(n, false);
+ // but now remove all children, since the call has been to remove("/")
+ n.removeAllChildren();
+ }
+ else
+ {
+ n.getParent().removeChild(n.getName());
+ }
+ }
+ else
+ {
+ if (log.isDebugEnabled()) log.debug("Node " + f + " NOT marked for removal as expected, not removing!");
+ }
+ }
+
+
/**
* Returns an <em>approximation</em> of the total number of attributes in
* the tree. Since this method doesn't acquire any locks, the number might
@@ -4481,6 +4560,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.
@@ -4555,6 +4637,8 @@
notifyNodeModify(fqn, true);
old_value = 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)
@@ -4645,8 +4729,27 @@
TreeNode parent_node;
MethodCall undo_op = null;
- if (log.isTraceEnabled())
- log.trace(new StringBuffer("_remove(").append(tx).append(", \"").append(fqn).append("\")"));
+ if (log.isTraceEnabled()) log.trace(new StringBuffer("_remove(").append(tx).append(", \"").append(fqn).append("\")"));
+
+ // 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);
+ }
+ }
if (fqn.size() == 0)
{
@@ -4687,13 +4790,17 @@
parent_node = n.getParent();
- // remove subtree from parent
+ if (isNodeLockingOptimistic() || eviction)
parent_node.removeChild(n.getName());
+ else
+ markForRemoval(n);
+
if (eviction)
parent_node.setChildrenLoaded(false);
// release all locks for the entire subtree
- n.releaseAll(tx != null ? tx : (Object) Thread.currentThread());
+ // JBCACHE-871 -- this is not correct! This is the lock interceptor's task
+ // n.releaseAll(tx != null ? tx : (Object) Thread.currentThread());
// create a compensating method call (reverting the effect of
// this modification) and put it into the TX's undo list.
@@ -4962,6 +5069,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));
}
@@ -5712,26 +5821,8 @@
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)
- {
- return null;
- }
- n = child_node;
- }
- toReturn = (DataNode) child_node;
- }
+
+ DataNode toReturn = findInternal(fqn, false);
if (version != null)
{
1.7.2.1 +14 -1 JBossCache/src/org/jboss/cache/TransactionTable.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TransactionTable.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/TransactionTable.java,v
retrieving revision 1.7
retrieving revision 1.7.2.1
diff -u -b -r1.7 -r1.7.2.1
--- TransactionTable.java 12 Jun 2006 20:24:32 -0000 1.7
+++ TransactionTable.java 5 Dec 2006 00:01:52 -0000 1.7.2.1
@@ -25,7 +25,7 @@
* given TX.
*
* @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 14, 2003
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.7.2.1 $
*/
public class TransactionTable {
@@ -202,6 +202,19 @@
}
/**
+ * Adds a node that has been removed to the global transaction
+ */
+ public void addRemovedNode(GlobalTransaction gtx, Fqn fqn)
+ {
+ TransactionEntry entry=get(gtx);
+ if(entry == null) {
+ log.error("transaction entry not found for (gtx=" + gtx + ")");
+ return;
+ }
+ entry.addRemovedNode(fqn);
+ }
+
+ /**
* Returns summary debug information.
*/
public String toString() {
More information about the jboss-cvs-commits
mailing list