X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Fimpl%2Fschema%2Ftree%2FModifiedNode.java;h=540eb9a632d57b47913c86d63cd5c43d435a681c;hb=7ae69e3edccd348635fdba5b2c8560e353da8b7c;hp=90e83ca401c213e269f8b61c0ba309c67b5775b8;hpb=1431a478d5b26fd00850a22a4e810007fcf990f4;p=yangtools.git diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java index 90e83ca401..540eb9a632 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java @@ -11,18 +11,17 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; import javax.annotation.Nonnull; -import org.opendaylight.yangtools.concepts.Identifiable; +import javax.annotation.concurrent.NotThreadSafe; 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.ModificationType; import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode; import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode; -import javax.annotation.concurrent.GuardedBy; -import java.util.LinkedHashMap; -import java.util.Map; - /** * Node Modification Node and Tree * @@ -30,11 +29,11 @@ import java.util.Map; * to the data store tree. * * This tree is lazily created and populated via {@link #modifyChild(PathArgument)} - * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}. + * and {@link TreeNode} which represents original state as tracked by {@link #getOriginal()}. */ -final class ModifiedNode implements StoreTreeNode, Identifiable, NodeModification { - - public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { +@NotThreadSafe +final class ModifiedNode extends NodeModification implements StoreTreeNode { + static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { @Override public boolean apply(final @Nonnull ModifiedNode input) { Preconditions.checkNotNull(input); @@ -59,7 +58,7 @@ final class ModifiedNode implements StoreTreeNode, Identifiable snapshotCache; private NormalizedNode value; - private ModifiedNode(final PathArgument identifier, final Optional original, boolean isOrdered) { + private ModifiedNode(final PathArgument identifier, final Optional original, final boolean isOrdered) { this.identifier = identifier; this.original = original; @@ -71,9 +70,9 @@ final class ModifiedNode implements StoreTreeNode, Identifiable getWrittenValue() { return value; @@ -90,7 +89,7 @@ final class ModifiedNode implements StoreTreeNode, Identifiable getOriginal() { + Optional getOriginal() { return original; } @@ -100,7 +99,7 @@ final class ModifiedNode implements StoreTreeNode, Identifiable, Identifiable, Identifiable getChildren() { + Iterable getChildren() { return children.values(); } /** - * * Records a delete for associated node. - * */ - public void delete() { + void delete() { final ModificationType newType; switch (modificationType) { @@ -201,29 +197,61 @@ final class ModifiedNode implements StoreTreeNode, Identifiable value) { + void write(final NormalizedNode value) { clearSnapshot(); updateModificationType(ModificationType.WRITE); children.clear(); this.value = value; } - public void merge(final NormalizedNode data) { + void merge(final NormalizedNode value) { clearSnapshot(); updateModificationType(ModificationType.MERGE); - // FIXME: Probably merge with previous value. - this.value = data; + + /* + * Blind overwrite of any previous data is okay, no matter whether the node + * is simple or complex type. + * + * If this is a simple or complex type with unkeyed children, this merge will + * be turned into a write operation, overwriting whatever was there before. + * + * If this is a container with keyed children, there are two possibilities: + * - if it existed before, this value will never be consulted and the children + * will get explicitly merged onto the original data. + * - if it did not exist before, this value will be used as a seed write and + * children will be merged into it. + * In either case we rely on OperationWithModification to manipulate the children + * before calling this method, so unlike a write we do not want to clear them. + */ + this.value = value; } + /** + * Seal the modification node and prune any children which has not been + * modified. + */ void seal() { clearSnapshot(); - for (ModifiedNode child : children.values()) { + + // Walk all child nodes and remove any children which have not + // been modified. + final Iterator it = children.values().iterator(); + while (it.hasNext()) { + final ModifiedNode child = it.next(); child.seal(); + + if (child.modificationType == ModificationType.UNMODIFIED) { + it.remove(); + } + } + + // A SUBTREE_MODIFIED node without any children is a no-op + if (modificationType == ModificationType.SUBTREE_MODIFIED && children.isEmpty()) { + updateModificationType(ModificationType.UNMODIFIED); } } @@ -231,16 +259,15 @@ final class ModifiedNode implements StoreTreeNode, Identifiable storeSnapshot(final Optional snapshot) { - snapshotCache = snapshot; - return snapshot; + Optional getSnapshot() { + return snapshotCache; } - public Optional> getSnapshotCache() { - return Optional.fromNullable(snapshotCache); + Optional setSnapshot(final Optional snapshot) { + snapshotCache = Preconditions.checkNotNull(snapshot); + return snapshot; } - @GuardedBy("this") private void updateModificationType(final ModificationType type) { modificationType = type; clearSnapshot(); @@ -252,7 +279,20 @@ final class ModifiedNode implements StoreTreeNode, Identifiable value) { + final ModifiedNode ret = new ModifiedNode(getIdentifier(), Optional.absent(), false); + ret.write(value); + return ret; + } + + public static ModifiedNode createUnmodified(final TreeNode metadataTree, final boolean isOrdered) { return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree), isOrdered); } }