Merge "Remove unused imports"
authorTony Tkacik <ttkacik@cisco.com>
Tue, 18 Nov 2014 09:20:26 +0000 (09:20 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 18 Nov 2014 09:20:26 +0000 (09:20 +0000)
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNormalizedNodeStreamWriter.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/AbstractImmutableDataContainerNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetEntryNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableLeafSetNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableMapNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableOrderedMapNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/builder/impl/ImmutableUnkeyedListNodeBuilder.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/AbstractImmutableDataContainerNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/UnmodifiableChildrenMap.java [new file with mode: 0644]

index fe3d1841a2bd8b67041aa66b7cddaa40120cb4e9..3ac6f32b0871a27a5982e77c25af8c83eb8ae642 100644 (file)
@@ -8,27 +8,38 @@
 package org.opendaylight.yangtools.yang.data.impl.schema;
 
 import com.google.common.base.Preconditions;
-
 import java.io.IOException;
 import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.List;
-
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
 
 /**
@@ -83,11 +94,10 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
      * <p>
      * This method is useful for clients, which knows there will be one
      * top level node written, but does not know which type of {@link NormalizedNode}
-     * will be writen.
-     *
+     * will be written.
      *
      * @param result {@link NormalizedNodeResult} object which will hold result value.
-     * @return {@link NormalizedNodeStreamWriter} whcih will write item to supplied result holder.
+     * @return {@link NormalizedNodeStreamWriter} which will write item to supplied result holder.
      */
     public static final NormalizedNodeStreamWriter from(final NormalizedNodeResult result) {
         return new ImmutableNormalizedNodeStreamWriter(new NormalizedNodeResultBuilder(result));
@@ -127,9 +137,10 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
     }
 
     @Override
-    public void startLeafSet(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+    public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
         checkDataNodeContainer();
-        ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = Builders.leafSetBuilder();
+        ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableLeafSetNodeBuilder.create() : ImmutableLeafSetNodeBuilder.create(childSizeHint);
         builder.withNodeIdentifier(name);
         enter(builder);
     }
@@ -145,53 +156,73 @@ public class ImmutableNormalizedNodeStreamWriter implements NormalizedNodeStream
     @Override
     public void anyxmlNode(final NodeIdentifier name, final Object value) throws IllegalArgumentException {
         checkDataNodeContainer();
-
-
     }
 
     @Override
-    public void startContainerNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+    public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
         checkDataNodeContainer();
-        enter(Builders.containerBuilder().withNodeIdentifier(name));
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableContainerNodeBuilder.create() : ImmutableContainerNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(name));
     }
 
     @Override
-    public void startUnkeyedList(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+    public void startUnkeyedList(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
         checkDataNodeContainer();
-        enter(Builders.unkeyedListBuilder().withNodeIdentifier(name));
+
+        final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableUnkeyedListNodeBuilder.create() : ImmutableUnkeyedListNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(name));
     }
 
     @Override
-    public void startUnkeyedListItem(final NodeIdentifier name,final int childSizeHint) throws IllegalStateException {
+    public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint) throws IllegalStateException {
         Preconditions.checkArgument(getCurrent() instanceof ImmutableUnkeyedListNodeBuilder);
-        enter(Builders.unkeyedListEntryBuilder().withNodeIdentifier(name));
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, UnkeyedListEntryNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableUnkeyedListEntryNodeBuilder.create() : ImmutableUnkeyedListEntryNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(name));
     }
 
     @Override
-    public void startMapNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+    public void startMapNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
         checkDataNodeContainer();
-        enter(Builders.mapBuilder().withNodeIdentifier(name));
+
+        final CollectionNodeBuilder<MapEntryNode, MapNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableMapNodeBuilder.create() : ImmutableMapNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(name));
     }
 
     @Override
-    public void startMapEntryNode(final NodeIdentifierWithPredicates identifier,final int childSizeHint) throws IllegalArgumentException {
+    public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint) throws IllegalArgumentException {
         if(!(getCurrent() instanceof NormalizedNodeResultBuilder)) {
             Preconditions.checkArgument(getCurrent() instanceof ImmutableMapNodeBuilder || getCurrent() instanceof ImmutableOrderedMapNodeBuilder);
         }
-        enter(Builders.mapEntryBuilder().withNodeIdentifier(identifier));
+
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableMapEntryNodeBuilder.create() : ImmutableMapEntryNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(identifier));
     }
 
     @Override
-    public void startOrderedMapNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+    public void startOrderedMapNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
         checkDataNodeContainer();
-        enter(Builders.orderedMapBuilder().withNodeIdentifier(name));
+
+        final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableOrderedMapNodeBuilder.create() : ImmutableOrderedMapNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(name));
     }
 
     @Override
-    public void startChoiceNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+    public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
         checkDataNodeContainer();
-        enter(Builders.choiceBuilder().withNodeIdentifier(name));
+
+        final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> builder = UNKNOWN_SIZE == childSizeHint ?
+                ImmutableChoiceNodeBuilder.create() : ImmutableChoiceNodeBuilder.create(childSizeHint);
+        enter(builder.withNodeIdentifier(name));
     }
+
     @Override
     public void startAugmentationNode(final AugmentationIdentifier identifier) throws IllegalArgumentException {
         checkDataNodeContainer();
index bb271684e967494043c1d13a7ff4f88d64856168..669c4d05abda672472ed480d1692e2afac3295d4 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 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.DataContainerChild;
@@ -20,7 +19,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNo
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
 
 abstract class AbstractImmutableDataContainerNodeBuilder<I extends YangInstanceIdentifier.PathArgument, R extends DataContainerNode<I>> implements DataContainerNodeBuilder<I, R> {
-
+    private static final int DEFAULT_CAPACITY = 4;
     private Map<YangInstanceIdentifier.PathArgument, DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> value;
     private I nodeIdentifier;
 
@@ -33,12 +32,12 @@ abstract class AbstractImmutableDataContainerNodeBuilder<I extends YangInstanceI
     private boolean dirty;
 
     protected AbstractImmutableDataContainerNodeBuilder() {
-        this.value = new HashMap<>();
+        this.value = new HashMap<>(DEFAULT_CAPACITY);
         this.dirty = false;
     }
 
     protected AbstractImmutableDataContainerNodeBuilder(final int sizeHint) {
-        this.value = new HashMap<>(sizeHint);
+        this.value = new HashMap<>(DEFAULT_CAPACITY);
         this.dirty = false;
     }
 
index 219f58c522165d174f7dc662f3fcc5371939cdf6..40c7a654d3fd8f33f5000ea24dd8839bffb64d7a 100644 (file)
@@ -7,15 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 
+import com.google.common.base.Preconditions;
 import java.util.Map;
-
+import java.util.Objects;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedValueAttrNode;
 
-import com.google.common.base.Preconditions;
-
 public class ImmutableLeafSetEntryNodeBuilder<T> extends AbstractImmutableNormalizedNodeBuilder<YangInstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> {
 
     public static <T> ImmutableLeafSetEntryNodeBuilder<T> create() {
@@ -31,7 +30,7 @@ public class ImmutableLeafSetEntryNodeBuilder<T> extends AbstractImmutableNormal
 
         ImmutableLeafSetEntryNode(final YangInstanceIdentifier.NodeWithValue nodeIdentifier, final T value, final Map<QName, String> attributes) {
             super(nodeIdentifier, value, attributes);
-            Preconditions.checkArgument(nodeIdentifier.getValue().equals(value),
+            Preconditions.checkArgument(Objects.deepEquals(nodeIdentifier.getValue(), value),
                     "Node identifier contains different value: %s than value itself: %s", nodeIdentifier, value);
         }
     }
index dd5048103c7a32f5ff3e9a62fe012ee27e4f354b..71b4bbc7606433dd53ee85ecbf709f21a99939dc 100644 (file)
@@ -7,11 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.util.MapAdaptor;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -25,16 +26,17 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNo
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedValueNode;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-
 public class ImmutableLeafSetNodeBuilder<T> implements ListNodeBuilder<T, LeafSetEntryNode<T>> {
-
+    private static final int DEFAULT_CAPACITY = 4;
     private final Map<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> value;
     private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
 
     protected ImmutableLeafSetNodeBuilder() {
-        value = new HashMap<>();
+        value = new HashMap<>(DEFAULT_CAPACITY);
+    }
+
+    protected ImmutableLeafSetNodeBuilder(final int sizeHint) {
+        value = new HashMap<>(sizeHint * 4 / 3);
     }
 
     protected ImmutableLeafSetNodeBuilder(final ImmutableLeafSetNode<T> node) {
@@ -46,6 +48,10 @@ public class ImmutableLeafSetNodeBuilder<T> implements ListNodeBuilder<T, LeafSe
         return new ImmutableLeafSetNodeBuilder<>();
     }
 
+    public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(final int sizeHint) {
+        return new ImmutableLeafSetNodeBuilder<>(sizeHint);
+    }
+
     public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(final LeafSetNode<T> node) {
         if (!(node instanceof ImmutableLeafSetNode<?>)) {
             throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
index 98028944ffe4146df5a67cf729f9ba2050a77d7a..226173cff7282dec7b06a863dd9b80eeb59bc1c8 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.util.MapAdaptor;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -22,17 +23,17 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-
-public class ImmutableMapNodeBuilder
-        implements CollectionNodeBuilder<MapEntryNode, MapNode> {
-
+public class ImmutableMapNodeBuilder implements CollectionNodeBuilder<MapEntryNode, MapNode> {
+    private static final int DEFAULT_CAPACITY = 4;
     private final Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value;
     private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
 
     protected ImmutableMapNodeBuilder() {
-        this.value = new HashMap<>();
+        this.value = new HashMap<>(DEFAULT_CAPACITY);
+    }
+
+    protected ImmutableMapNodeBuilder(final int sizeHint) {
+        this.value = new HashMap<>(DEFAULT_CAPACITY);
     }
 
     protected ImmutableMapNodeBuilder(final ImmutableMapNode node) {
@@ -44,6 +45,10 @@ public class ImmutableMapNodeBuilder
         return new ImmutableMapNodeBuilder();
     }
 
+    public static CollectionNodeBuilder<MapEntryNode, MapNode> create(final int sizeHint) {
+        return new ImmutableMapNodeBuilder(sizeHint);
+    }
+
     public static CollectionNodeBuilder<MapEntryNode, MapNode> create(final MapNode node) {
         if (!(node instanceof ImmutableMapNode)) {
             throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
index e7d68d992894f7a87b39039b12cf58545f847723..523ad51817a5b27af9ffa6865f33a0c9d17074da 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Iterables;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -20,19 +23,19 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNo
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
 
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ImmutableOrderedMapNodeBuilder
-        implements CollectionNodeBuilder<MapEntryNode, OrderedMapNode> {
-
+public class ImmutableOrderedMapNodeBuilder implements CollectionNodeBuilder<MapEntryNode, OrderedMapNode> {
+    private static final int DEFAULT_CAPACITY = 4;
     private Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value;
     private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
-    private boolean dirty = false;
+    private boolean dirty;
 
     protected ImmutableOrderedMapNodeBuilder() {
-        this.value = new LinkedHashMap<>();
+        this.value = new LinkedHashMap<>(DEFAULT_CAPACITY);
+        this.dirty = false;
+    }
+
+    protected ImmutableOrderedMapNodeBuilder(final int sizeHint) {
+        this.value = new LinkedHashMap<>(DEFAULT_CAPACITY);
         this.dirty = false;
     }
 
@@ -46,6 +49,10 @@ public class ImmutableOrderedMapNodeBuilder
         return new ImmutableOrderedMapNodeBuilder();
     }
 
+    public static CollectionNodeBuilder<MapEntryNode, OrderedMapNode> create(final int sizeHint) {
+        return new ImmutableOrderedMapNodeBuilder(sizeHint);
+    }
+
     public static CollectionNodeBuilder<MapEntryNode, OrderedMapNode> create(final MapNode node) {
         if (!(node instanceof ImmutableOrderedMapNode)) {
             throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
@@ -145,9 +152,9 @@ public class ImmutableOrderedMapNodeBuilder
             return children.size();
         }
 
-               @Override
-               public Iterable<MapEntryNode> getValue() {
-                       return Iterables.unmodifiableIterable(children.values());
-               }
+        @Override
+        public Iterable<MapEntryNode> getValue() {
+            return Iterables.unmodifiableIterable(children.values());
+        }
     }
 }
index 66f81cadff5f75bc1b23cc9cbf915395830fda13..9eab2ba09816bd45d76faca4344d4b06273767f8 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
-
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -21,14 +23,10 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNo
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedValueNode;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
 public class ImmutableUnkeyedListNodeBuilder implements CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> {
-
     private List<UnkeyedListEntryNode> value;
     private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
-    private boolean dirty = false;
+    private boolean dirty;
 
     protected ImmutableUnkeyedListNodeBuilder() {
         this.value = new LinkedList<>();
@@ -46,6 +44,10 @@ public class ImmutableUnkeyedListNodeBuilder implements CollectionNodeBuilder<Un
         return new ImmutableUnkeyedListNodeBuilder();
     }
 
+    public static CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> create(final int sizeHint) {
+        return new ImmutableUnkeyedListNodeBuilder();
+    }
+
     public static CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> create(final UnkeyedListNode node) {
         if (!(node instanceof ImmutableUnkeyedListNode)) {
             throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
@@ -95,7 +97,11 @@ public class ImmutableUnkeyedListNodeBuilder implements CollectionNodeBuilder<Un
     @Override
     public UnkeyedListNode build() {
         dirty = true;
-        return new ImmutableUnkeyedListNode(nodeIdentifier, ImmutableList.copyOf(value));
+        if (value.isEmpty()) {
+            return new EmptyImmutableUnkeyedListNode(nodeIdentifier);
+        } else {
+            return new ImmutableUnkeyedListNode(nodeIdentifier, ImmutableList.copyOf(value));
+        }
     }
 
     @Override
@@ -109,6 +115,37 @@ public class ImmutableUnkeyedListNodeBuilder implements CollectionNodeBuilder<Un
         return withoutChild(key);
     }
 
+    protected static final class EmptyImmutableUnkeyedListNode extends AbstractImmutableNormalizedNode<YangInstanceIdentifier.NodeIdentifier, Iterable<UnkeyedListEntryNode>> implements Immutable, UnkeyedListNode {
+        protected EmptyImmutableUnkeyedListNode(final NodeIdentifier nodeIdentifier) {
+            super(nodeIdentifier);
+        }
+
+        @Override
+        public Iterable<UnkeyedListEntryNode> getValue() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public UnkeyedListEntryNode getChild(final int position) {
+            return null;
+        }
+
+        @Override
+        public int getSize() {
+            return 0;
+        }
+
+        @Override
+        protected boolean valueEquals(final AbstractImmutableNormalizedNode<?, ?> other) {
+            return Collections.EMPTY_LIST.equals(other.getValue());
+        }
+
+        @Override
+        protected int valueHashCode() {
+            return Collections.EMPTY_LIST.hashCode();
+        }
+    }
+
     protected static final class ImmutableUnkeyedListNode extends
             AbstractImmutableNormalizedValueNode<YangInstanceIdentifier.NodeIdentifier, Iterable<UnkeyedListEntryNode>>
             implements Immutable, UnkeyedListNode {
index 01bfe32b2811d9afaf93040f6c8c112af899bdf7..a4b426885827003dfb9f3fdbb79db6b9b9c54013 100644 (file)
@@ -8,49 +8,20 @@
 package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
 
 import com.google.common.base.Optional;
-
-import java.util.Collections;
 import java.util.Map;
-
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public abstract class AbstractImmutableDataContainerNode<K extends PathArgument> extends AbstractImmutableNormalizedNode<K, Iterable<DataContainerChild<? extends PathArgument, ?>>> implements Immutable, DataContainerNode<K> {
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractImmutableDataContainerNode.class);
     private final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> children;
 
     public AbstractImmutableDataContainerNode(
             final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> children, final K nodeIdentifier) {
         super(nodeIdentifier);
 
-        /*
-         * There is a code path where AbstractImmutableDataContainerNodeBuilder can reflect
-         * the collection acquired via getChildren() back to us. This is typically the case
-         * in the datastore where transactions cancel each other out, leaving an unmodified
-         * node. In that case we want to skip wrapping the map again (and again and again).
-         *
-         * In a perfect world, Collection.unmodifiableMap() would be doing the instanceof
-         * check which would stop the proliferation. Unfortunately this not the case and the
-         * 'unmodifiable' trait is not exposed by anything we can query. Furthermore the API
-         * contract there is sufficiently vague so an implementation may actually return a
-         * different implementation based on input map -- for example
-         * Collections.unmodifiableMap(Collections.emptyMap()) returning the same thing as
-         * Collections.emptyMap().
-         *
-         * This means that we have to perform the instantiation here (as opposed to once at
-         * class load time) and then compare the classes.
-         */
-        final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> pub = Collections.unmodifiableMap(children);
-        if (children.getClass().equals(pub.getClass())) {
-            LOG.trace("Reusing already-unmodifiable children {}", children);
-            this.children = children;
-        } else {
-            this.children = pub;
-        }
+        this.children = UnmodifiableChildrenMap.create(children);
     }
 
     @Override
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/UnmodifiableChildrenMap.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/nodes/UnmodifiableChildrenMap.java
new file mode 100644 (file)
index 0000000..49887cc
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.yangtools.yang.data.impl.schema.nodes;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Internal equivalent of {@link Collections}' unmodifiable Map. It does not retain
+ * keySet/entrySet references, thus lowering the memory overhead.
+ */
+final class UnmodifiableChildrenMap implements Map<PathArgument, DataContainerChild<? extends PathArgument, ?>>, Serializable {
+    private static final Logger LOG = LoggerFactory.getLogger(UnmodifiableChildrenMap.class);
+    private static final long serialVersionUID = 1L;
+    private final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> delegate;
+    private transient Collection<DataContainerChild<? extends PathArgument, ?>> values;
+
+    private UnmodifiableChildrenMap(final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> delegate) {
+        this.delegate = Preconditions.checkNotNull(delegate);
+    }
+
+    /**
+     * Create an unmodifiable view of a particular map. Does not perform unnecessary
+     * encapsulation if the map is known to be already unmodifiable.
+     *
+     * @param map Backing map
+     * @return Unmodifiable view
+     */
+    static Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> create(final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> map) {
+        if (map instanceof UnmodifiableChildrenMap) {
+            return map;
+        }
+        if (map instanceof ImmutableMap) {
+            return map;
+        }
+        if (map.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        return new UnmodifiableChildrenMap(map);
+    }
+
+    @Override
+    public int size() {
+        return delegate.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return delegate.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(final Object key) {
+        return delegate.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(final Object value) {
+        return delegate.containsValue(value);
+    }
+
+    @Override
+    public DataContainerChild<? extends PathArgument, ?> get(final Object key) {
+        return delegate.get(key);
+    }
+
+    @Override
+    public DataContainerChild<? extends PathArgument, ?> put(final PathArgument key,
+            final DataContainerChild<? extends PathArgument, ?> value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DataContainerChild<? extends PathArgument, ?> remove(final Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void putAll(final Map<? extends PathArgument, ? extends DataContainerChild<? extends PathArgument, ?>> m) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<PathArgument> keySet() {
+        return Collections.unmodifiableSet(delegate.keySet());
+    }
+
+    @Override
+    public Collection<DataContainerChild<? extends PathArgument, ?>> values() {
+        if (values == null) {
+            values = Collections.unmodifiableCollection(delegate.values());
+        }
+        return values;
+    }
+
+    @Override
+    public Set<Entry<PathArgument, DataContainerChild<? extends PathArgument, ?>>> entrySet() {
+        LOG.warn("Invocation of inefficient entrySet()", new Throwable().fillInStackTrace());
+        return Collections.unmodifiableMap(delegate).entrySet();
+    }
+
+
+    @Override
+    public boolean equals(final Object o) {
+        return this == o || delegate.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return delegate.toString();
+    }
+}