Use a dedicated typedef resolver 48/29348/3
authorRobert Varga <rovarga@cisco.com>
Mon, 2 Nov 2015 16:24:50 +0000 (17:24 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 16 Nov 2015 12:03:02 +0000 (12:03 +0000)
DataNodeIterator is excessively expensive for extraction of a list of
typedefs. Create a dedicated class to do that.

Change-Id: Ibf980bfe85113b5d996754c4ba6e32fd14d5ab69
Signed-off-by: Robert Varga <rovarga@cisco.com>
binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypedefResolver.java [new file with mode: 0644]

index 501b6c324ad0fe55ac31f9a8d4b45b6f60e3697d..96f93e4aee8b51461de733a01f51f9a643413cd4 100644 (file)
@@ -11,7 +11,6 @@ import static org.opendaylight.yangtools.binding.generator.util.BindingGenerator
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
-
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Sets;
 import com.google.common.io.BaseEncoding;
@@ -78,7 +77,6 @@ import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
 import org.opendaylight.yangtools.yang.model.util.EnumerationType;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.Int16;
@@ -696,8 +694,7 @@ public final class TypeProviderImpl implements TypeProvider {
             }
             final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
 
-            final DataNodeIterator it = new DataNodeIterator(module);
-            final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
+            final List<TypeDefinition<?>> typeDefinitions = TypedefResolver.getAllTypedefs(module);
             final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
 
             if ((listTypeDefinitions != null) && (basePackageName != null)) {
diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypedefResolver.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypedefResolver.java
new file mode 100644 (file)
index 0000000..9d9aad1
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013 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.sal.binding.yang.types;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+final class TypedefResolver {
+    private TypedefResolver() {
+        throw new UnsupportedOperationException();
+    }
+
+    static List<TypeDefinition<?>> getAllTypedefs(final Module module) {
+        final List<TypeDefinition<?>> ret = new ArrayList<>();
+
+        fillRecursively(ret, module);
+
+        final Set<NotificationDefinition> notifications = module.getNotifications();
+        for (NotificationDefinition notificationDefinition : notifications) {
+            fillRecursively(ret, notificationDefinition);
+        }
+
+        final Set<RpcDefinition> rpcs = module.getRpcs();
+        for (RpcDefinition rpcDefinition : rpcs) {
+            ret.addAll(rpcDefinition.getTypeDefinitions());
+            ContainerSchemaNode input = rpcDefinition.getInput();
+            if (input != null) {
+                fillRecursively(ret, input);
+            }
+            ContainerSchemaNode output = rpcDefinition.getInput();
+            if (input != null) {
+                fillRecursively(ret, output);
+            }
+        }
+
+        return ret;
+    }
+
+    private static void fillRecursively(final List<TypeDefinition<?>> list, final DataNodeContainer container) {
+        final Collection<DataSchemaNode> childNodes = container.getChildNodes();
+        if (childNodes != null) {
+            for (DataSchemaNode childNode : childNodes) {
+                if (!childNode.isAugmenting()) {
+                    if (childNode instanceof ContainerSchemaNode) {
+                        fillRecursively(list, (ContainerSchemaNode) childNode);
+                    } else if (childNode instanceof ListSchemaNode) {
+                        fillRecursively(list, (ListSchemaNode) childNode);
+                    } else if (childNode instanceof ChoiceSchemaNode) {
+                        final Set<ChoiceCaseNode> cases = ((ChoiceSchemaNode) childNode).getCases();
+                        if (cases != null) {
+                            for (final ChoiceCaseNode caseNode : cases) {
+                                fillRecursively(list, caseNode);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        list.addAll(container.getTypeDefinitions());
+
+        final Set<GroupingDefinition> groupings = container.getGroupings();
+        if (groupings != null) {
+            for (GroupingDefinition grouping : groupings) {
+                fillRecursively(list, grouping);
+            }
+        }
+    }
+}