BUG-5280: move AbstractDataTreeModificationCursor 40/39840/38
authorRobert Varga <rovarga@cisco.com>
Fri, 3 Jun 2016 12:28:42 +0000 (14:28 +0200)
committerRobert Varga <rovarga@cisco.com>
Wed, 22 Jun 2016 15:09:58 +0000 (17:09 +0200)
AbstractDataTreeModificationCursor functionality is useful for wide
range of users, move it to sal-clustering-commons.

Also eliminate the explicit stack, because YangInstanceIdentifier
already has O(1) methods to maintain a logical stack.

Change-Id: Ia0f8d24f32afd67c059e72cc967949f4c609fd7c
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/util/AbstractDataTreeModificationCursor.java [moved from opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/AbstractDataTreeModificationCursor.java with 52% similarity]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/AbstractBatchedModificationsCursor.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/DataTreeModificationOutput.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/utils/PruningDataTreeModification.java

@@ -5,68 +5,74 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.controller.cluster.datastore.utils;
+package org.opendaylight.controller.cluster.datastore.util;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import java.util.ArrayDeque;
-import java.util.Deque;
+import com.google.common.base.Verify;
 import javax.annotation.Nonnull;
+import javax.annotation.concurrent.NotThreadSafe;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
 
 /**
- * Base class for a DataTreeModificationCursor.
+ * Abstract {@link DataTreeModificationCursor} which tracks the current path. Subclasses can get the current path
+ * via {@link #current()}.
  *
  * @author Thomas Pantelis
  */
+@Beta
+@NotThreadSafe
 public abstract class AbstractDataTreeModificationCursor implements DataTreeModificationCursor {
-    private final Deque<YangInstanceIdentifier> stack = new ArrayDeque<>();
+    private YangInstanceIdentifier current = YangInstanceIdentifier.EMPTY;
 
-    protected AbstractDataTreeModificationCursor() {
-        stack.push(YangInstanceIdentifier.EMPTY);
-    }
-
-    protected YangInstanceIdentifier next(@Nonnull final PathArgument child) {
-        return stack.peek().node(child);
+    protected final YangInstanceIdentifier current() {
+        return current;
     }
 
     @Override
-    public void enter(@Nonnull final PathArgument child) {
-        stack.push(stack.peek().node(child));
+    public final void enter(@Nonnull final PathArgument child) {
+        current = current.node(child);
     }
 
     @Override
-    public void enter(@Nonnull final PathArgument... path) {
+    public final void enter(@Nonnull final PathArgument... path) {
         for (PathArgument arg : path) {
             enter(arg);
         }
     }
 
     @Override
-    public void enter(@Nonnull final Iterable<PathArgument> path) {
+    public final void enter(@Nonnull final Iterable<PathArgument> path) {
         for (PathArgument arg : path) {
             enter(arg);
         }
     }
 
     @Override
-    public void exit() {
-        stack.pop();
+    public final void exit() {
+        Preconditions.checkState(!current.isEmpty());
+        current = Verify.verifyNotNull(current.getParent());
     }
 
     @Override
-    public void exit(final int depth) {
-        Preconditions.checkArgument(depth < stack.size(), "Stack holds only %s elements, cannot exit %s levels", stack.size(), depth);
+    public final void exit(final int depth) {
+        Preconditions.checkArgument(depth >= 0);
+
+        YangInstanceIdentifier next = current;
         for (int i = 0; i < depth; ++i) {
-            stack.pop();
+            next = next.getParent();
+            Preconditions.checkState(next != null);
         }
+
+        current = next;
     }
 
     @Override
-    public Optional<NormalizedNode<?, ?>> readNode(@Nonnull final PathArgument child) {
+    public final Optional<NormalizedNode<?, ?>> readNode(@Nonnull final PathArgument child) {
         throw new UnsupportedOperationException("Not implemented");
     }
 
index ecddebc..d859f67 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.cluster.datastore.messages.BatchedModificatio
 import org.opendaylight.controller.cluster.datastore.modification.DeleteModification;
 import org.opendaylight.controller.cluster.datastore.modification.MergeModification;
 import org.opendaylight.controller.cluster.datastore.modification.WriteModification;
+import org.opendaylight.controller.cluster.datastore.util.AbstractDataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
@@ -20,20 +21,21 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  * @author Thomas Pantelis
  */
 public abstract class AbstractBatchedModificationsCursor extends AbstractDataTreeModificationCursor {
+
     protected abstract BatchedModifications getModifications();
 
     @Override
-    public void delete(final PathArgument child) {
-        getModifications().addModification(new DeleteModification(next(child)));
+    public final void delete(final PathArgument child) {
+        getModifications().addModification(new DeleteModification(current().node(child)));
     }
 
     @Override
-    public void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
-        getModifications().addModification(new MergeModification(next(child), data));
+    public final void merge(final PathArgument child, final NormalizedNode<?, ?> data) {
+        getModifications().addModification(new MergeModification(current().node(child), data));
     }
 
     @Override
-    public void write(final PathArgument child, final NormalizedNode<?, ?> data) {
-        getModifications().addModification(new WriteModification(next(child), data));
+    public final void write(final PathArgument child, final NormalizedNode<?, ?> data) {
+        getModifications().addModification(new WriteModification(current().node(child), data));
     }
 }
index 17d4c4a..8e19441 100644 (file)
@@ -13,6 +13,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import javax.xml.stream.XMLStreamException;
+import org.opendaylight.controller.cluster.datastore.util.AbstractDataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
@@ -49,7 +50,7 @@ public final class DataTreeModificationOutput {
         public void delete(PathArgument child) {
             try {
                 output.write("\nDELETE -> ".getBytes());
-                output.write(next(child).toString().getBytes());
+                output.write(current().node(child).toString().getBytes());
                 output.writeByte('\n');
             } catch(IOException e) {
                 Throwables.propagate(e);
@@ -71,7 +72,7 @@ public final class DataTreeModificationOutput {
                 output.writeByte('\n');
                 output.write(name.getBytes());
                 output.write(" -> ".getBytes());
-                output.write(next(child).toString().getBytes());
+                output.write(current().node(child).toString().getBytes());
                 output.write(": \n".getBytes());
                 NormalizedNodeXMLOutput.toStream(output, data);
                 output.writeByte('\n');
index a44b686..69e2c88 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import java.io.IOException;
 import org.opendaylight.controller.cluster.datastore.node.utils.transformer.NormalizedNodePruner;
+import org.opendaylight.controller.cluster.datastore.util.AbstractDataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -155,7 +156,7 @@ public class PruningDataTreeModification implements DataTreeModification {
 
         @Override
         public void write(PathArgument child, NormalizedNode<?, ?> data) {
-            YangInstanceIdentifier path = next(child);
+            YangInstanceIdentifier path = current().node(child);
             NormalizedNode<?, ?> prunedNode = pruningModification.pruneNormalizedNode(path, data);
             if(prunedNode != null) {
                 toModification.write(path, prunedNode);
@@ -164,7 +165,7 @@ public class PruningDataTreeModification implements DataTreeModification {
 
         @Override
         public void merge(PathArgument child, NormalizedNode<?, ?> data) {
-            YangInstanceIdentifier path = next(child);
+            YangInstanceIdentifier path = current().node(child);
             NormalizedNode<?, ?> prunedNode = pruningModification.pruneNormalizedNode(path, data);
             if(prunedNode != null) {
                 toModification.merge(path, prunedNode);
@@ -174,7 +175,7 @@ public class PruningDataTreeModification implements DataTreeModification {
         @Override
         public void delete(PathArgument child) {
             try {
-                toModification.delete(next(child));
+                toModification.delete(current().node(child));
             } catch(SchemaValidationFailedException e) {
                 // Ignoring since we would've already logged this in the call to the original modification.
             }