BUG-509: remove unnecessary Version objects 15/7515/2
authorRobert Varga <rovarga@cisco.com>
Wed, 28 May 2014 22:02:17 +0000 (00:02 +0200)
committerRobert Varga <rovarga@cisco.com>
Thu, 29 May 2014 14:51:24 +0000 (16:51 +0200)
Testing has revealed the datastore instantiates effectively a version
per tree node. This turns out to be not needed, as we really just need a
single version per commit -- which can be shared between nodes, as the
(node,version) tuple remains unique.

So let's just instantiate a single version when we start the
transaction, which we need to do anyway, and use it for all
nodes/subtrees added or modified. This places an upper bound on Version
objects retained to the number of transactions committed (not counting
no-ops).

Change-Id: I40d095ec230eee8b5af2409c1e8ee61a1860a9d3
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java

index 15479be..c09a1a3 100644 (file)
@@ -16,7 +16,7 @@ import com.google.common.base.Optional;
 final class AlwaysFailOperation implements ModificationApplyOperation {
     @Override
     public Optional<TreeNode> apply(final ModifiedNode modification,
-            final Optional<TreeNode> storeMeta, final Version subtreeVersion) {
+            final Optional<TreeNode> storeMeta, final Version version) {
         throw new IllegalStateException("Schema Context is not available.");
     }
 
index 10f39a8..df03db3 100644 (file)
@@ -50,7 +50,7 @@ interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOper
      * @param storeMeta
      *            Store Metadata Node on which NodeModification should be
      *            applied
-     * @param subtreeVersion New subtree version of parent node
+     * @param version New subtree version of parent node
      * @throws IllegalArgumentException
      *             If it is not possible to apply Operation on provided Metadata
      *             node
@@ -58,7 +58,7 @@ interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOper
      *         node, {@link Optional#absent()} if {@link ModifiedNode}
      *         resulted in deletion of this node.
      */
-    Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version subtreeVersion);
+    Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version version);
 
     /**
      *
index 3a3af5e..b70c5d1 100644 (file)
@@ -95,16 +95,9 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp
 
     @Override
     protected TreeNode applyWrite(final ModifiedNode modification,
-            final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
-        final Version nodeVersion;
-        if (currentMeta.isPresent()) {
-            nodeVersion = currentMeta.get().getVersion().next();
-        } else {
-            nodeVersion = subtreeVersion;
-        }
-
+            final Optional<TreeNode> currentMeta, final Version version) {
         final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
-        final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, nodeVersion);
+        final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version);
 
         if (Iterables.isEmpty(modification.getChildren())) {
             return newValueMeta;
@@ -122,12 +115,12 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp
          * and run the common parts on it -- which end with the node being sealed.
          */
         final MutableTreeNode mutable = newValueMeta.mutable();
-        mutable.setSubtreeVersion(subtreeVersion);
+        mutable.setSubtreeVersion(version);
 
         @SuppressWarnings("rawtypes")
         final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
 
-        return mutateChildren(mutable, dataBuilder, nodeVersion, modification.getChildren());
+        return mutateChildren(mutable, dataBuilder, version, modification.getChildren());
     }
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
@@ -155,24 +148,21 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp
 
     @Override
     protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
-            final Version subtreeVersion) {
+            final Version version) {
         // For Node Containers - merge is same as subtree change - we only replace children.
-        return applySubtreeChange(modification, currentMeta, subtreeVersion);
+        return applySubtreeChange(modification, currentMeta, version);
     }
 
     @Override
     public TreeNode applySubtreeChange(final ModifiedNode modification,
-            final TreeNode currentMeta, final Version subtreeVersion) {
-        // Bump subtree version to its new target
-        final Version updatedSubtreeVersion = currentMeta.getSubtreeVersion().next();
-
+            final TreeNode currentMeta, final Version version) {
         final MutableTreeNode newMeta = currentMeta.mutable();
-        newMeta.setSubtreeVersion(updatedSubtreeVersion);
+        newMeta.setSubtreeVersion(version);
 
         @SuppressWarnings("rawtypes")
         NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
 
-        return mutateChildren(newMeta, dataBuilder, updatedSubtreeVersion, modification.getChildren());
+        return mutateChildren(newMeta, dataBuilder, version, modification.getChildren());
     }
 
     @Override
index ff90d57..e1cc1a1 100644 (file)
@@ -44,8 +44,8 @@ final class OperationWithModification {
         return applyOperation;
     }
 
-    public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version subtreeVersion) {
-        return applyOperation.apply(modification, data, subtreeVersion);
+    public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version version) {
+        return applyOperation.apply(modification, data, version);
     }
 
     public static OperationWithModification from(final ModificationApplyOperation operation,
index bdf5667..6ef76ad 100644 (file)
@@ -184,7 +184,7 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
 
     @Override
     public final Optional<TreeNode> apply(final ModifiedNode modification,
-            final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
+            final Optional<TreeNode> currentMeta, final Version version) {
 
         switch (modification.getType()) {
         case DELETE:
@@ -193,13 +193,13 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
             Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
                     modification);
             return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
-                    subtreeVersion)));
+                    version)));
         case MERGE:
             if(currentMeta.isPresent()) {
-                return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion)));
+                return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(), version)));
             } // Fallback to write is intentional - if node is not preexisting merge is same as write
         case WRITE:
-            return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion)));
+            return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, version)));
         case UNMODIFIED:
             return currentMeta;
         default:
@@ -208,13 +208,13 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
     }
 
     protected abstract TreeNode applyMerge(ModifiedNode modification,
-            TreeNode currentMeta, Version subtreeVersion);
+            TreeNode currentMeta, Version version);
 
     protected abstract TreeNode applyWrite(ModifiedNode modification,
-            Optional<TreeNode> currentMeta, Version subtreeVersion);
+            Optional<TreeNode> currentMeta, Version version);
 
     protected abstract TreeNode applySubtreeChange(ModifiedNode modification,
-            TreeNode currentMeta, Version subtreeVersion);
+            TreeNode currentMeta, Version version);
 
     protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification,
             final Optional<TreeNode> current) throws DataPreconditionFailedException;
@@ -231,20 +231,20 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
 
         @Override
         protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
-                final Version subtreeVersion) {
-            return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+                final Version version) {
+            return applyWrite(modification, Optional.of(currentMeta), version);
         }
 
         @Override
         protected TreeNode applySubtreeChange(final ModifiedNode modification,
-                final TreeNode currentMeta, final Version subtreeVersion) {
+                final TreeNode currentMeta, final Version version) {
             throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
         }
 
         @Override
         protected TreeNode applyWrite(final ModifiedNode modification,
-                final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
-            return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+                final Optional<TreeNode> currentMeta, final Version version) {
+            return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);
         }
 
         @Override
index 5f68782..a9f69ac 100644 (file)
@@ -48,22 +48,22 @@ abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends S
 
     @Override
     protected TreeNode applySubtreeChange(final ModifiedNode modification,
-            final TreeNode currentMeta, final Version subtreeVersion) {
+            final TreeNode currentMeta, final Version version) {
         throw new UnsupportedOperationException("Node " + schema.getPath()
                 + "is leaf type node. Subtree change is not allowed.");
     }
 
     @Override
     protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
-            final Version subtreeVersion) {
+            final Version version) {
         // Just overwrite whatever was there
-        return applyWrite(modification, null, subtreeVersion);
+        return applyWrite(modification, null, version);
     }
 
     @Override
     protected TreeNode applyWrite(final ModifiedNode modification,
-            final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
-        return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+            final Optional<TreeNode> currentMeta, final Version version) {
+        return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);
     }
 
     @Override