Author: manik.surtani(a)jboss.com
Date: 2008-07-07 10:39:36 -0400 (Mon, 07 Jul 2008)
New Revision: 6186
Modified:
core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java
core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java
core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java
core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java
Log:
Improved various mvcc impl details
Modified: core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-07-07 14:38:55 UTC
(rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java 2008-07-07 14:39:36 UTC
(rev 6186)
@@ -523,6 +523,11 @@
return children;
}
+ public Map<Object, Node<K, V>> getChildrenMapDirect(boolean init)
+ {
+ return init ? children() : children;
+ }
+
public void setChildrenMapDirect(Map<Object, Node<K, V>> children)
{
if (children == null)
@@ -747,14 +752,8 @@
protected void copyInternals(UnversionedNode n)
{
- if (children == null || children.isEmpty())
- {
- n.children = null;
- }
- else
- {
- n.children().putAll(children);
- }
+ // direct reference to child map
+ n.children = children;
n.commandsFactory = commandsFactory;
n.delegate = delegate;
n.flags.clear();
Modified:
core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/commands/legacy/read/PessGetChildrenNamesCommand.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -1,9 +1,14 @@
package org.jboss.cache.commands.legacy.read;
import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.read.GetChildrenNamesCommand;
import org.jboss.cache.invocation.InvocationContext;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
public class PessGetChildrenNamesCommand extends GetChildrenNamesCommand
{
public PessGetChildrenNamesCommand()
@@ -15,9 +20,18 @@
super(fqn);
}
- @Override
- public Object perform(InvocationContext ctx)
+ protected Set<Object> getCorrectedChildNames(Collection<NodeSPI> children,
InvocationContext ctx)
{
- return fetchChildrenNames(ctx);
+ // prune deleted children - JBCACHE-1136
+ Set<Object> childNames = new HashSet<Object>();
+ for (NodeSPI child : children)
+ {
+ if (!child.isDeleted())
+ {
+ Object e = child.getFqn().getLastElement();
+ childNames.add(e);
+ }
+ }
+ return childNames;
}
}
Modified:
core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/commands/legacy/write/PessRemoveNodeCommand.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -50,6 +50,11 @@
return found;
}
+ @Override
+ protected void recursivelyMarkAsRemoved(NodeSPI node, InvocationContext ctx)
+ {
+ node.markAsDeleted(true, true);
+ }
private void prepareForRollback(NodeSPI parentNode)
{
Modified:
core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/commands/read/GetChildrenNamesCommand.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -9,6 +9,7 @@
import org.jboss.cache.mvcc.ReadCommittedNode;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -37,64 +38,58 @@
this.fqn = fqn;
}
- protected final Set<Object> fetchChildrenNames(InvocationContext ctx)
+ /**
+ * Retrieves the names of children for a specific Fqn.
+ *
+ * @param ctx invocation context
+ * @return a Set<Object> of child names, for a given Fqn, or null if the Fqn
refers to a node that does not exist.
+ */
+ @SuppressWarnings("unchecked")
+ public Object perform(InvocationContext ctx)
{
NodeSPI n = fqn == null ? null : ctx.lookUpNode(fqn);
if (n == null || n.isDeleted()) return null;
Map childrenMap = n.getChildrenMapDirect();
- if (childrenMap == null || childrenMap.isEmpty()) return new
HashSet<Object>();
- Set<Object> childNames = new HashSet<Object>();
- Collection s = childrenMap.values();
- // prune deleted children - JBCACHE-1136
- for (Object c : s)
- {
- NodeSPI child = (NodeSPI) c;
- if (!child.isDeleted())
- {
- Object e = child.getFqn().getLastElement();
- childNames.add(e);
- }
- }
- return childNames;
+ Collection<NodeSPI> children = (childrenMap == null || childrenMap.isEmpty())
? Collections.emptySet() : childrenMap.values();
+
+ return getCorrectedChildNames(children, ctx);
}
-
/**
- * Retrieves the names of children for a specific Fqn.
+ * Cleans the collection of children passed in to extract child names into a Set.
This implementation provides
+ * additional filtering such as removing known deleted children and adding known
created ones.
*
- * @param ctx invocation context
- * @return a Set<Object> of child names, for a given Fqn, or null if the Fqn
refers to a node that does not exist.
+ * @param children children set. Must not be null.
+ * @param ctx invocation context
+ * @return a set of valid children names.
*/
- public Object perform(InvocationContext ctx)
+ protected Set<Object> getCorrectedChildNames(Collection<NodeSPI> children,
InvocationContext ctx)
{
- Set<Object> childNames = fetchChildrenNames(ctx);
+ Set<Object> childNames = new HashSet<Object>();
- if (trace) log.trace("Got child name set as " + childNames);
- // check for *new* children added.
- boolean modified = false;
+ for (NodeSPI realChild : children)
+ {
+ Fqn childFqn = realChild.getFqn();
+ NodeSPI childNode = ctx.lookUpNode(childFqn);
+
+ // deletion flag should be checked on what we get from the ctx.
+ // if childNode is null then it hasn't been removed in the current scope and
hence should be included in this list.
+ if (childNode == null || !childNode.isDeleted())
childNames.add(childFqn.getLastElement());
+ }
+
+ // now check for any *new* children added.
for (Map.Entry<Fqn, NodeSPI> n : ctx.getLookedUpNodes().entrySet())
{
Fqn childFqn = n.getKey();
if (childFqn.getParent().equals(fqn))
{
- NodeSPI childNode = n.getValue();
- if (childNode.isDeleted())
- {
- childNames.remove(childFqn.getLastElement());
- modified = true;
- }
- else if (((ReadCommittedNode) childNode).isCreated())
- {
- childNames.add(childFqn.getLastElement());
- modified = true;
- }
+ ReadCommittedNode childNode = (ReadCommittedNode) n.getValue();
+ if (childNode.isCreated()) childNames.add(childFqn.getLastElement());
}
}
- if (trace && modified) log.trace("Modified child set to " +
childNames);
return childNames;
}
-
public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
{
return visitor.visitGetChildrenNamesCommand(ctx, this);
Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java 2008-07-07
14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetNodeCommand.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -1,5 +1,7 @@
package org.jboss.cache.commands.read;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.Visitor;
@@ -17,6 +19,8 @@
public class GetNodeCommand extends AbstractDataCommand
{
public static final int METHOD_ID = 31;
+ private static final Log log = LogFactory.getLog(GetNodeCommand.class);
+ private static final boolean trace = log.isTraceEnabled();
public GetNodeCommand(Fqn fqn)
{
@@ -36,7 +40,13 @@
public Object perform(InvocationContext ctx)
{
NodeSPI node = ctx.lookUpNode(fqn);
- if (node != null && node.isDeleted()) return null;
+ if (node != null && node.isDeleted())
+ {
+ if (trace)
+ log.trace("Node of type [" + node.getClass().getSimpleName() +
"] found but marked as deleted in current scope. Returning null.");
+ return null;
+ }
+ if (trace) log.trace("Found node, returning " + node);
return node;
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java 2008-07-07
14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/commands/write/EvictCommand.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -126,7 +126,7 @@
parentNode.setChildrenLoaded(false);
}
node.setValid(false, false);
- node.markAsDeleted(true, false);
+ node.markAsDeleted(true);
return true;
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/commands/write/RemoveNodeCommand.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -9,6 +9,8 @@
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.transaction.GlobalTransaction;
+import java.util.Map;
+
/**
* Implements functionality defined by {@link
org.jboss.cache.CacheSPI#removeNode(org.jboss.cache.Fqn)}
*
@@ -54,7 +56,7 @@
notifyBeforeRemove(targetNode, ctx);
boolean found = targetNode.isValid() && !targetNode.isDeleted();
- targetNode.markAsDeleted(true, true);
+ recursivelyMarkAsRemoved(targetNode, ctx);
// make sure we clear all data on this node!
targetNode.clearDataDirect();
@@ -63,6 +65,24 @@
return found;
}
+ /**
+ * Recursively marks a node as removed.
+ *
+ * @param node Node to mark
+ * @param ctx Invocation context
+ */
+ protected void recursivelyMarkAsRemoved(NodeSPI node, InvocationContext ctx)
+ {
+ node.markAsDeleted(true);
+ Fqn parentFqn = node.getFqn();
+ // recursion has to happen like this since child nodes are in the ctx.
+ Map<Fqn, NodeSPI> nodes = ctx.getLookedUpNodes();
+ for (Map.Entry<Fqn, NodeSPI> entry : nodes.entrySet())
+ {
+ if (entry.getKey().isChildOf(parentFqn)) entry.getValue().markAsDeleted(true);
+ }
+ }
+
private void notifyBeforeRemove(NodeSPI n, InvocationContext ctx)
{
if (!skipSendingNodeEvents)
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/interceptors/MVCCLockingInterceptor.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -360,7 +360,7 @@
protected void doAfterCall(InvocationContext ctx, VisitableCommand command)
{
// for non-transactional stuff.
- if (ctx.getTransaction() == null)
+ if (ctx.getTransactionContext() == null)
{
List<Fqn> locks;
if (!(locks = ctx.getLocks()).isEmpty())
@@ -381,12 +381,21 @@
}
ctx.clearLocks();
}
+ else
+ {
+ if (trace) log.trace("Nothing to do since there are no modifications in
scope.");
+ }
}
+ else
+ {
+ if (trace)
+ log.trace("Nothing to do since there is a transaction in scope.
Deferring writing changes. Ctx=" + ctx);
+ }
}
protected void transactionalCleanup(boolean commit, InvocationContext ctx)
{
- if (ctx.getTransaction() != null)
+ if (ctx.getTransactionContext() != null)
{
List<Fqn> locks;
if (!(locks = ctx.getTransactionContext().getLocks()).isEmpty())
@@ -418,6 +427,10 @@
ctx.clearLocks();
}
}
+ else
+ {
+ throw new IllegalStateException("Attempting to do a commit or rollback but
there is no transactional context in scope. " + ctx);
+ }
}
// ----------------- actual implementation details ----------------------------
@@ -431,15 +444,21 @@
{
if (forceWriteLock)
{
+ if (trace) log.trace("Forcing lock on reading node " + f);
getWrappedNode(ctx, f, true, false, false);
}
else if (ctx.lookUpNode(f) == null)
{
+ if (trace) log.trace("Node " + f + " is not in context,
fetching from container.");
// simple implementation. Peek the node, wrap it, put wrapped node in the
context.
InternalNode node = dataContainer.peekInternalNode(f, false);
NodeSPI wrapped = nodeFactory.createMvccNode(node);
if (wrapped != null) ctx.putLookedUpNode(f, wrapped);
}
+ else
+ {
+ if (trace) log.trace("Node " + f + " is already in
context.");
+ }
}
return invokeNextInterceptor(ctx, command);
}
Modified:
core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -198,6 +198,7 @@
return "InvocationContext{" +
"transaction=" + transaction +
", globalTransaction=" + globalTransaction +
+ ", transactionContext=" + transactionContext +
", optionOverrides=" + optionOverrides +
", originLocal=" + originLocal +
", txHasMods=" + txHasMods +
Modified: core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
===================================================================
---
core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java 2008-07-07
14:38:55 UTC (rev 6185)
+++
core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -290,12 +290,14 @@
if (child == null)
{
+ if (trace) log.trace("Child is null; creating.");
Option o2 = o1.copy();
spi.getInvocationContext().setOptionOverrides(o1);
spi.put(nf, null);
-
+ if (trace) log.trace("Created. Now getting again.");
spi.getInvocationContext().setOptionOverrides(o2);
child = getChild(f);
+ if (trace) log.trace("Got child " + child);
}
return child;
}
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java 2008-07-07 14:38:55
UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/InternalNode.java 2008-07-07 14:39:36
UTC (rev 6186)
@@ -109,6 +109,12 @@
boolean isResident();
+ /**
+ * Creates a new instance of the same type and copies internal state. Note that a
shallow copy is made for all fields
+ * except the data map, where a new map is created.
+ *
+ * @return a copy.
+ */
InternalNode copy();
NodeLock getLock();
@@ -116,4 +122,12 @@
void addChild(Object nodeName, Node<K, V> nodeToAdd);
void printDetails(StringBuilder sb, int indent);
+
+ /**
+ * Very similar to getChildrenMapDirect() except that if the internal map is null, it
initialises the map if init is true.
+ *
+ * @param init if true, will init internal data structures.
+ * @return a Map or null.
+ */
+ Map<Object, Node<K, V>> getChildrenMapDirect(boolean init);
}
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java 2008-07-07 14:38:55
UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/NodeReference.java 2008-07-07 14:39:36
UTC (rev 6186)
@@ -136,6 +136,11 @@
return delegate.getChildrenMapDirect();
}
+ public Map getChildrenMapDirect(boolean b)
+ {
+ return delegate.getChildrenMapDirect(b);
+ }
+
public void setChildrenMapDirect(Map children)
{
delegate.setChildrenMapDirect(children);
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2008-07-07
14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -10,10 +10,6 @@
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.optimistic.DefaultDataVersion;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
/**
* Repeatable read would do a simple delegation to the underlying node.
*
@@ -25,7 +21,8 @@
protected volatile InternalNode backup;
protected boolean changed;
protected boolean created;
- protected Set childrenAdded, childrenRemoved;
+ protected boolean deleted;
+// protected Set childrenAdded, childrenRemoved;
public ReadCommittedNode(InternalNode node)
{
@@ -51,51 +48,77 @@
{
if (changed)
{
- updateNode(container, nf, ctx);
+ Fqn fqn = getFqn();
+ if (trace)
+ log.trace("Updating node [" + fqn + "]. deleted=" +
isDeleted() + " valid=" + isValid() + " changed" + isChanged() +
" created=" + created);
+
+ // check if node has been deleted.
+ if (deleted)
+ {
+ if (!fqn.isRoot())
+ {
+ NodeSPI parent = lookupParent(fqn, ctx, container);
+ parent.removeChildDirect(fqn.getLastElement());
+ }
+ else
+ {
+ log.warn("Attempting to remove the root node. Not doing
anything!");
+ }
+ }
+ else if (created)
+ {
+ // add newly created nodes to parents.
+ NodeSPI parent = lookupParent(fqn, ctx, container);
+ parent.addChildDirect(nf.createNodeInvocationDelegate(node));
+ }
+ else if (fqn.isRoot())
+ {
+ // set root node reference in data container.
+ container.setRoot(nf.createNodeInvocationDelegate(node));
+ }
+ else
+ {
+ updateNode(container, nf, ctx);
+ }
+
changed = false;
backup = null;
}
}
- protected NodeSPI lookupParent(Fqn fqn, InvocationContext ctx, DataContainer
container)
+ /**
+ * Performs a lookup for the parent node of the Fqn passed in. The context is checked
first, and failing that, the
+ * data container is consulted.
+ *
+ * @param fqn Fqn whos parent to locate
+ * @param ctx invocation context
+ * @param container data container
+ * @return Parent node, never null.
+ * @throws NodeNotExistsException if the parent node cannot be found in any scope or
data container.
+ */
+ protected final NodeSPI lookupParent(Fqn fqn, InvocationContext ctx, DataContainer
container) throws NodeNotExistsException
{
Fqn parentFqn = fqn.getParent();
NodeSPI parent = ctx.lookUpNode(parentFqn);
if (parent != null) return parent;
parent = container.peek(parentFqn);
+ if (parent == null)
+ throw new NodeNotExistsException("Node " + parentFqn + " cannot
be found in any context or data container!");
return parent;
}
- protected void updateNode(DataContainer container, NodeFactory nf, InvocationContext
ctx)
+ /**
+ * Updates state changes on the current node in the underlying data structure.
+ *
+ * @param dataContainer data container
+ * @param nf node factory
+ * @param ctx invocation context
+ */
+ protected void updateNode(DataContainer dataContainer, NodeFactory nf,
InvocationContext ctx)
{
- Fqn fqn = getFqn();
- if (trace)
- log.trace("Updating node [" + fqn + "]. deleted=" +
isDeleted() + " valid=" + isValid() + " changed" + isChanged() +
" created=" + created);
- if (isDeleted())
- {
- if (!fqn.isRoot())
- {
- NodeSPI parent = lookupParent(fqn, ctx, container);
- parent.removeChildDirect(fqn.getLastElement());
- }
- else
- {
- log.warn("Attempting to remove the root node. Not doing
anything!");
- }
- }
- else if (created)
- {
- NodeSPI parent = lookupParent(fqn, ctx, container);
- if (parent == null)
- throw new NodeNotExistsException("Cannot add node " + fqn + "
to data structure since its parent is null!");
- parent.addChildDirect(nf.createNodeInvocationDelegate(node));
- }
- else
- {
- mergeChildren(backup.getChildrenMapDirect());
- ((NodeReference) backup).setDelegate(((NodeReference) node).getDelegate());
- node = backup;
- }
+ // swap refs
+ ((NodeReference) backup).setDelegate(((NodeReference) node).getDelegate());
+ node = backup;
}
public void rollbackUpdate()
@@ -135,42 +158,23 @@
return backup;
}
+ // do not propagate deletion flags to the underlying node.
+
@Override
- public void addChildDirect(NodeSPI child)
+ public boolean isDeleted()
{
- Object childname = child.getFqn().getLastElement();
- if (childrenAdded == null) childrenAdded = new HashSet();
- childrenAdded.add(childname);
- if (childrenRemoved != null) childrenRemoved.remove(childname);
- super.addChildDirect(child);
+ return deleted;
}
@Override
- public boolean removeChildDirect(Object childname)
+ public void markAsDeleted(boolean deleted)
{
- boolean rv = super.removeChildDirect(childname);
- if (rv)
- {
- if (childrenRemoved == null) childrenRemoved = new HashSet();
- childrenRemoved.add(childname);
- if (childrenAdded != null) childrenAdded.remove(childname);
- }
- return rv;
+ this.deleted = deleted;
}
- protected void mergeChildren(Map oldChildren)
+ @Override
+ public void markAsDeleted(boolean deleted, boolean recursive)
{
- if (oldChildren == null || oldChildren.isEmpty()) return; // nothing to do.
- Map childmap = node.getChildrenMapDirect();
- node.setChildrenMapDirect(oldChildren);
- if (childrenRemoved != null)
- {
- for (Object name : childrenRemoved) node.removeChildDirect(name);
- }
-
- if (childrenAdded != null)
- {
- for (Object name : childrenAdded) node.addChildDirect((NodeSPI)
childmap.get(name));
- }
+ throw new UnsupportedOperationException("Recursive deletion not
allowed!");
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java 2008-07-07
14:38:55 UTC (rev 6185)
+++ core/trunk/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java 2008-07-07
14:39:36 UTC (rev 6186)
@@ -3,7 +3,6 @@
import org.jboss.cache.DataContainer;
import org.jboss.cache.Fqn;
import org.jboss.cache.NodeFactory;
-import org.jboss.cache.NodeNotExistsException;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.invocation.InvocationContext;
import org.jboss.cache.optimistic.DataVersion;
@@ -54,41 +53,7 @@
@Override
protected void updateNode(DataContainer dataContainer, NodeFactory nf,
InvocationContext ctx)
{
- Fqn fqn = getFqn();
- if (trace)
- log.trace("Updating node [" + fqn + "]. deleted=" +
isDeleted() + " valid=" + isValid() + " changed" + isChanged() +
" created=" + created);
-
- if (fqn.isRoot())
- {
- dataContainer.setRoot(nf.createNodeInvocationDelegate(node));
- }
- else if (created)
- {
- NodeSPI parent = lookupParent(fqn, ctx, dataContainer);
- if (parent == null)
- throw new NodeNotExistsException("Cannot add node " + fqn + "
to data structure since its parent is null!");
- parent.addChildDirect(nf.createNodeInvocationDelegate(node));
- }
- else
- {
- NodeSPI parent = lookupParent(fqn, ctx, dataContainer);
- if (parent != null)
- {
- Object name = fqn.getLastElement();
- NodeSPI oldChild = parent.getChildDirect(name);
- if (isDeleted())
- {
- parent.removeChildDirect(name);
- }
- else
- {
- if (oldChild != null)
- {
- mergeChildren(oldChild.getChildrenMapDirect());
- }
- parent.addChildDirect(nf.createNodeInvocationDelegate(node));
- }
- }
- }
+ NodeSPI parent = lookupParent(getFqn(), ctx, dataContainer);
+ parent.addChildDirect(nf.createNodeInvocationDelegate(node));
}
}