[jbosscache-commits] JBoss Cache SVN: r6186 - in core/trunk/src/main/java/org/jboss/cache: commands/legacy/read and 6 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Mon Jul 7 10:39:36 EDT 2008


Author: manik.surtani at 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));
    }
 }




More information about the jbosscache-commits mailing list