BUG-582: do not use linear search of child nodes 11/7811/4
authorRobert Varga <rovarga@cisco.com>
Sat, 7 Jun 2014 21:05:13 +0000 (23:05 +0200)
committerRobert Varga <rovarga@cisco.com>
Wed, 18 Jun 2014 09:43:47 +0000 (11:43 +0200)
Profiling has found we are epending some time in addChildNode() to
search all the existing node. As it turns out, we are already using a
TreeSet, so using a TreeMap instead will give us a log(N) lookup
capability at no cost at all.

Change-Id: I5e3962170d8d5ae8bb087de3de52928ad6cebc1c
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceCaseBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingBuilderImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ListSchemaNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/NotificationBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java

index 9a86e5ca2f03ff78c9310201cb286d0b7a9dadf3..ebb12dbc00ddf4ea565ba733beaf21072afdc956 100644 (file)
@@ -8,7 +8,9 @@ package org.opendaylight.yangtools.yang.parser.builder.api;
 
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.TreeSet;
 
 import org.opendaylight.yangtools.yang.common.QName;
@@ -25,7 +27,7 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder implements DataNodeContainerBuilder {
     protected final QName qname;
 
-    protected final Set<DataSchemaNode> childNodes = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
+    protected final Map<QName, DataSchemaNode> childNodes = new TreeMap<>();
     protected final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<>();
 
     protected final Set<GroupingDefinition> groupings = new TreeSet<>(Comparators.SCHEMA_NODE_COMP);
@@ -47,7 +49,7 @@ public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder i
         return qname;
     }
 
-    public Set<DataSchemaNode> getChildNodes() {
+    public Map<QName, DataSchemaNode> getChildNodes() {
         return childNodes;
     }
 
@@ -67,7 +69,7 @@ public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder i
     }
 
     @Override
-    public void addChildNode(DataSchemaNodeBuilder child) {
+    public void addChildNode(final DataSchemaNodeBuilder child) {
         QName childName = child.getQName();
         for (DataSchemaNodeBuilder addedChildNode : addedChildNodes) {
             if (addedChildNode.getQName().equals(childName)) {
@@ -80,21 +82,19 @@ public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder i
     }
 
     @Override
-    public void addChildNodeToContext(DataSchemaNodeBuilder child) {
+    public void addChildNodeToContext(final DataSchemaNodeBuilder child) {
         addedChildNodes.add(child);
     }
 
     @Override
-    public void addChildNode(DataSchemaNode child) {
+    public void addChildNode(final DataSchemaNode child) {
         QName childName = child.getQName();
-        for (DataSchemaNode childNode : childNodes) {
-            if (childNode.getQName().equals(childName)) {
-                throw new YangParseException(getModuleName(), getLine(), String.format(
-                        "Can not add '%s' to '%s' in module '%s': node with same name already declared", child, this,
-                        getModuleName()));
-            }
+        if (childNodes.containsKey(childName)) {
+            throw new YangParseException(getModuleName(), getLine(),
+                    String.format("Can not add '%s' to '%s' in module '%s': node with same name already declared",
+                            child, this, getModuleName()));
         }
-        childNodes.add(child);
+        childNodes.put(childName, child);
     }
 
     @Override
@@ -111,7 +111,7 @@ public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder i
     }
 
     @Override
-    public void addGrouping(GroupingBuilder grouping) {
+    public void addGrouping(final GroupingBuilder grouping) {
         QName groupingName = grouping.getQName();
         for (GroupingBuilder addedGrouping : addedGroupings) {
             if (addedGrouping.getQName().equals(groupingName)) {
@@ -138,11 +138,11 @@ public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder i
     }
 
     @Override
-    public void addUsesNode(UsesNodeBuilder usesNode) {
+    public void addUsesNode(final UsesNodeBuilder usesNode) {
         addedUsesNodes.add(usesNode);
     }
 
-    protected static DataSchemaNode getChildNode(Set<DataSchemaNode> childNodes, QName name) {
+    protected static DataSchemaNode getChildNode(final Set<DataSchemaNode> childNodes, final QName name) {
         for (DataSchemaNode node : childNodes) {
             if (node.getQName().equals(name)) {
                 return node;
@@ -151,7 +151,7 @@ public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder i
         return null;
     }
 
-    protected static DataSchemaNode getChildNode(Set<DataSchemaNode> childNodes, String name) {
+    protected static DataSchemaNode getChildNode(final Set<DataSchemaNode> childNodes, final String name) {
         for (DataSchemaNode node : childNodes) {
             if (node.getQName().getLocalName().equals(name)) {
                 return node;
index d25586ed3bcd781ca73b8a10acb98ef8c0584bb2..add657ea568cc9380141ea2d40d52dd173079002 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.parser.builder.impl;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -18,6 +14,7 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
@@ -40,6 +37,11 @@ import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.util.ParserUtils;
 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
 public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContainerBuilder implements
         AugmentationSchemaBuilder {
     private final int order;
@@ -57,7 +59,7 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
     private boolean resolved;
     private AugmentationSchemaBuilder copyOf;
 
-    public AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr, int order) {
+    public AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr, final int order) {
         super(moduleName, line, null);
         this.order = order;
         this.augmentTargetStr = augmentTargetStr;
@@ -129,9 +131,9 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
 
         // CHILD NODES
         for (DataSchemaNodeBuilder node : addedChildNodes) {
-            childNodes.add(node.build());
+            childNodes.put(node.getQName(), node.build());
         }
-        instance.childNodes = ImmutableSet.copyOf(childNodes);
+        instance.childNodes = ImmutableSet.copyOf(childNodes.values());
 
         // USES
         for (UsesNodeBuilder builder : addedUsesNodes) {
@@ -453,7 +455,7 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
         }
 
         @Override
-        public int compareTo(AugmentationSchemaImpl o) {
+        public int compareTo(final AugmentationSchemaImpl o) {
             Iterator<QName> thisIt = this.targetPath.getPath().iterator();
             Iterator<QName> otherIt = o.getTargetPath().getPath().iterator();
             while (thisIt.hasNext()) {
index 82c648f7d83623f0a4a663f914d9f9041a4695a4..bd94b0f6cc3997aeb7aa555fd2979af4060ff5de 100644 (file)
@@ -102,9 +102,9 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
 
         // CHILD NODES
         for (DataSchemaNodeBuilder node : addedChildNodes) {
-            childNodes.add(node.build());
+            childNodes.put(node.getQName(), node.build());
         }
-        instance.childNodes = ImmutableSet.copyOf(childNodes);
+        instance.childNodes = ImmutableSet.copyOf(childNodes.values());
 
         // USES
         for (UsesNodeBuilder builder : addedUsesNodes) {
@@ -163,7 +163,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
     }
 
     @Override
-    public void setStatus(Status status) {
+    public void setStatus(final Status status) {
         this.status = Preconditions.checkNotNull(status, "status cannot be null");
     }
 
index f0a143e57ca74317bb87d0925cf2410b650fabcb..516837151081a16ef985bcdcc1571f754689431c 100644 (file)
@@ -109,9 +109,9 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
         // CHILD NODES
         for (DataSchemaNodeBuilder node : addedChildNodes) {
-            childNodes.add(node.build());
+            childNodes.put(node.getQName(), node.build());
         }
-        instance.childNodes = ImmutableSet.copyOf(childNodes);
+        instance.childNodes = ImmutableSet.copyOf(childNodes.values());
 
         // GROUPINGS
         for (GroupingBuilder builder : addedGroupings) {
@@ -168,7 +168,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     }
 
     @Override
-    public void addAugmentation(AugmentationSchemaBuilder augment) {
+    public void addAugmentation(final AugmentationSchemaBuilder augment) {
         augmentationBuilders.add(augment);
     }
 
@@ -178,7 +178,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     }
 
     @Override
-    public void setPath(SchemaPath path) {
+    public void setPath(final SchemaPath path) {
         this.path = path;
     }
 
@@ -208,7 +208,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     }
 
     @Override
-    public void setStatus(Status status) {
+    public void setStatus(final Status status) {
         this.status = Preconditions.checkNotNull(status, "status cannot be null");
     }
 
@@ -218,7 +218,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     }
 
     @Override
-    public void setAugmenting(boolean augmenting) {
+    public void setAugmenting(final boolean augmenting) {
         this.augmenting = augmenting;
     }
 
@@ -238,7 +238,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     }
 
     @Override
-    public void setConfiguration(boolean configuration) {
+    public void setConfiguration(final boolean configuration) {
         this.configuration = configuration;
     }
 
@@ -251,7 +251,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         return presence;
     }
 
-    public void setPresence(boolean presence) {
+    public void setPresence(final boolean presence) {
         this.presence = presence;
     }
 
@@ -264,7 +264,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     }
 
     @Override
-    public boolean equals(Object obj) {
+    public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
@@ -319,7 +319,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
         private boolean presence;
 
-        private ContainerSchemaNodeImpl(QName qname, SchemaPath path) {
+        private ContainerSchemaNodeImpl(final QName qname, final SchemaPath path) {
             this.qname = qname;
             this.path = path;
         }
@@ -385,12 +385,12 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         }
 
         @Override
-        public DataSchemaNode getDataChildByName(QName name) {
+        public DataSchemaNode getDataChildByName(final QName name) {
             return getChildNode(childNodes, name);
         }
 
         @Override
-        public DataSchemaNode getDataChildByName(String name) {
+        public DataSchemaNode getDataChildByName(final String name) {
             return getChildNode(childNodes, name);
         }
 
@@ -424,7 +424,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         }
 
         @Override
-        public boolean equals(Object obj) {
+        public boolean equals(final Object obj) {
             if (this == obj) {
                 return true;
             }
index e628c43e4c5bb8af376a018b425548e8443503ad..ced13261d0d85ffd0f9d02469b46134d83bdab11 100644 (file)
@@ -87,9 +87,9 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
 
         // CHILD NODES
         for (DataSchemaNodeBuilder node : addedChildNodes) {
-            childNodes.add(node.build());
+            childNodes.put(node.getQName(), node.build());
         }
-        instance.childNodes = ImmutableSet.copyOf(childNodes);
+        instance.childNodes = ImmutableSet.copyOf(childNodes.values());
 
         // GROUPINGS
         for (GroupingBuilder builder : addedGroupings) {
@@ -119,7 +119,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public Set<DataSchemaNodeBuilder> instantiateChildNodes(Builder newParent) {
+    public Set<DataSchemaNodeBuilder> instantiateChildNodes(final Builder newParent) {
         final Set<DataSchemaNodeBuilder> nodes = new HashSet<>();
         for (DataSchemaNodeBuilder node : addedChildNodes) {
             DataSchemaNodeBuilder copy = CopyUtils.copy(node, newParent, true);
@@ -130,7 +130,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public Set<TypeDefinitionBuilder> instantiateTypedefs(Builder newParent) {
+    public Set<TypeDefinitionBuilder> instantiateTypedefs(final Builder newParent) {
         final Set<TypeDefinitionBuilder> nodes = new HashSet<>();
         for (TypeDefinitionBuilder node : addedTypedefs) {
             TypeDefinitionBuilder copy = CopyUtils.copy(node, newParent, true);
@@ -140,7 +140,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public Set<GroupingBuilder> instantiateGroupings(Builder newParent) {
+    public Set<GroupingBuilder> instantiateGroupings(final Builder newParent) {
         final Set<GroupingBuilder> nodes = new HashSet<>();
         for (GroupingBuilder node : addedGroupings) {
             GroupingBuilder copy = CopyUtils.copy(node, newParent, true);
@@ -154,7 +154,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public Set<UnknownSchemaNodeBuilder> instantiateUnknownNodes(Builder newParent) {
+    public Set<UnknownSchemaNodeBuilder> instantiateUnknownNodes(final Builder newParent) {
         final Set<UnknownSchemaNodeBuilder> nodes = new HashSet<>();
         for (UnknownSchemaNodeBuilder node : addedUnknownNodes) {
             UnknownSchemaNodeBuilder copy = CopyUtils.copy(node, newParent, true);
@@ -215,7 +215,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public void setStatus(Status status) {
+    public void setStatus(final Status status) {
         this.status = Preconditions.checkNotNull(status, "status cannot be null");
     }
 
@@ -244,7 +244,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public boolean equals(Object obj) {
+    public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
@@ -349,12 +349,12 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
         }
 
         @Override
-        public DataSchemaNode getDataChildByName(QName name) {
+        public DataSchemaNode getDataChildByName(final QName name) {
             return getChildNode(childNodes, name);
         }
 
         @Override
-        public DataSchemaNode getDataChildByName(String name) {
+        public DataSchemaNode getDataChildByName(final String name) {
             return getChildNode(childNodes, name);
         }
 
@@ -368,7 +368,7 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder
         }
 
         @Override
-        public boolean equals(Object obj) {
+        public boolean equals(final Object obj) {
             if (this == obj) {
                 return true;
             }
index 79cdf048e9a8e9222da5f7a6cb98907c52a1cd07..4b533284f73abcd0c0782f55a5251d8239e21810 100644 (file)
@@ -112,9 +112,9 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
 
         // CHILD NODES
         for (DataSchemaNodeBuilder node : addedChildNodes) {
-            childNodes.add(node.build());
+            childNodes.put(node.getQName(), node.build());
         }
-        instance.childNodes = ImmutableSet.copyOf(childNodes);
+        instance.childNodes = ImmutableSet.copyOf(childNodes.values());
 
         // KEY
         if (keys == null) {
@@ -183,7 +183,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     }
 
     @Override
-    public void setPath(SchemaPath path) {
+    public void setPath(final SchemaPath path) {
         this.schemaPath = path;
     }
 
@@ -213,7 +213,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     }
 
     @Override
-    public void setStatus(Status status) {
+    public void setStatus(final Status status) {
         this.status = Preconditions.checkNotNull(status, "status cannot be null");
     }
 
@@ -240,7 +240,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     }
 
     @Override
-    public void setAugmenting(boolean augmenting) {
+    public void setAugmenting(final boolean augmenting) {
         this.augmenting = augmenting;
     }
 
@@ -260,7 +260,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     }
 
     @Override
-    public void setConfiguration(boolean configuration) {
+    public void setConfiguration(final boolean configuration) {
         this.configuration = configuration;
     }
 
index 13600af18885dce86b6a5b4c06a7a05e1a92dce4..9650deb85fa9abf715ca69ccd31a600b21a3f29e 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.yangtools.yang.parser.builder.impl;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Deque;
@@ -143,7 +144,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
         revision = base.getRevision();
 
         for (DataSchemaNode childNode : base.getChildNodes()) {
-            childNodes.add(childNode);
+            childNodes.put(childNode.getQName(), childNode);
         }
 
         typedefs.addAll(base.getTypeDefinitions());
@@ -181,9 +182,9 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
 
         // CHILD NODES
         for (DataSchemaNodeBuilder child : addedChildNodes) {
-            childNodes.add(child.build());
+            childNodes.put(child.getQName(), child.build());
         }
-        instance.addChildNodes(childNodes);
+        instance.addChildNodes(childNodes.values());
 
         // GROUPINGS
         for (GroupingBuilder gb : addedGroupings) {
@@ -1115,7 +1116,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             return Collections.unmodifiableSet(childNodes);
         }
 
-        private void addChildNodes(final Set<DataSchemaNode> childNodes) {
+        private void addChildNodes(final Collection<DataSchemaNode> childNodes) {
             if (childNodes != null) {
                 this.childNodes.addAll(childNodes);
             }
index 967c901425a5088b03a872900492f2ca2799eada..8d7e4b669e0966b28533b21fbaad2fb0e38842e8 100644 (file)
@@ -93,9 +93,9 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
 
         // CHILD NODES
         for (DataSchemaNodeBuilder node : addedChildNodes) {
-            childNodes.add(node.build());
+            childNodes.put(node.getQName(), node.build());
         }
-        instance.childNodes = ImmutableSet.copyOf(childNodes);
+        instance.childNodes = ImmutableSet.copyOf(childNodes.values());
 
         // GROUPINGS
         for (GroupingBuilder builder : addedGroupings) {
@@ -147,7 +147,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public void setPath(SchemaPath path) {
+    public void setPath(final SchemaPath path) {
         this.schemaPath = path;
     }
 
@@ -177,7 +177,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
     }
 
     @Override
-    public void setStatus(Status status) {
+    public void setStatus(final Status status) {
         this.status = Preconditions.checkNotNull(status, "status cannot be null");
     }
 
index c02cc5d1615cfb7df6d54e10d57ee4298f02220b..7803775a95a9e7857abf43728d98aab5fbd1b6cc 100644 (file)
@@ -449,7 +449,7 @@ public final class YangParserImpl implements YangContextParser {
         module.getAugmentBuilders().addAll(submodule.getAugmentBuilders());
         module.getAllAugments().addAll(submodule.getAllAugments());
         module.getChildNodeBuilders().addAll(submodule.getChildNodeBuilders());
-        module.getChildNodes().addAll(submodule.getChildNodes());
+        module.getChildNodes().putAll(submodule.getChildNodes());
         module.getGroupings().addAll(submodule.getGroupings());
         module.getGroupingBuilders().addAll(submodule.getGroupingBuilders());
         module.getTypeDefinitions().addAll(submodule.getTypeDefinitions());