Eliminate childNodes map 18/86018/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 25 Nov 2019 15:06:50 +0000 (16:06 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 27 Nov 2019 08:42:26 +0000 (09:42 +0100)
Both AbstractEffectiveDocumentedDataNodeContainer and
AbstractEffectiveModule are subclasses of
AbstractSchemaEffectiveDocumentedNode, which contains schema tree
index.

As all DataSchemaNodes have to strictly be a subset of the schema
tree, we can ditch the dedicated index and simply perform a lookup
on the schema tree followed by a check for DataSchemaNode.

JIRA: YANGTOOLS-1043
Change-Id: I79d5b8ceeb6c16aef162eda9c2a8430b7a9c98f7
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 3a3b4422017da67c4f37c06b2e286c3a69c6d0c1)

yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDocumentedDataNodeContainer.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractSchemaEffectiveDocumentedNode.java

index e7f3cf00d07f432d86c5d5c2a771877798bc5a5d..3f472c7887941aaad386a4e7b79f9a43d96e6027 100644 (file)
@@ -7,9 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -31,7 +28,6 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends DeclaredStatement<A>>
         extends AbstractSchemaEffectiveDocumentedNode<A, D> implements DataNodeContainer {
 
-    private final ImmutableMap<QName, DataSchemaNode> childNodes;
     private final ImmutableSet<GroupingDefinition> groupings;
     private final ImmutableSet<UsesNode> uses;
     private final ImmutableSet<TypeDefinition<?>> typeDefinitions;
@@ -68,7 +64,6 @@ public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends
             }
         }
 
-        this.childNodes = ImmutableMap.copyOf(mutableChildNodes);
         this.groupings = ImmutableSet.copyOf(mutableGroupings);
         this.publicChildNodes = ImmutableSet.copyOf(mutablePublicChildNodes);
         this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
@@ -92,8 +87,7 @@ public abstract class AbstractEffectiveDocumentedDataNodeContainer<A, D extends
 
     @Override
     public final Optional<DataSchemaNode> findDataChildByName(final QName name) {
-        // Child nodes are keyed by their container name, so we can do a direct lookup
-        return Optional.ofNullable(childNodes.get(requireNonNull(name)));
+        return findDataSchemaNode(name);
     }
 
     @Override
index d2da6974d1c91009d85eaf340b78e1b9a9bb6f29..8376d38cea715d7c9251406728726f6a044ef1a5 100644 (file)
@@ -12,7 +12,6 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import java.net.URI;
 import java.util.ArrayList;
@@ -71,7 +70,6 @@ public abstract class AbstractEffectiveModule<D extends DeclaredStatement<String
     private final ImmutableSet<Deviation> deviations;
     private final ImmutableList<ExtensionDefinition> extensionNodes;
     private final ImmutableSet<IdentitySchemaNode> identities;
-    private final ImmutableMap<QName, DataSchemaNode> childNodes;
     private final ImmutableSet<GroupingDefinition> groupings;
     private final ImmutableSet<UsesNode> uses;
     private final ImmutableSet<TypeDefinition<?>> typeDefinitions;
@@ -167,7 +165,6 @@ public abstract class AbstractEffectiveModule<D extends DeclaredStatement<String
         this.features = ImmutableSet.copyOf(featuresInit);
         this.extensionNodes = ImmutableList.copyOf(extensionNodesInit);
 
-        this.childNodes = ImmutableMap.copyOf(mutableChildNodes);
         this.groupings = ImmutableSet.copyOf(mutableGroupings);
         this.publicChildNodes = ImmutableSet.copyOf(mutablePublicChildNodes);
         this.typeDefinitions = ImmutableSet.copyOf(mutableTypeDefinitions);
@@ -267,8 +264,7 @@ public abstract class AbstractEffectiveModule<D extends DeclaredStatement<String
     @Override
     @SuppressWarnings("checkstyle:hiddenField")
     public final Optional<DataSchemaNode> findDataChildByName(final QName name) {
-        // Child nodes are keyed by their container name, so we can do a direct lookup
-        return Optional.ofNullable(childNodes.get(requireNonNull(name)));
+        return findDataSchemaNode(name);
     }
 
     @Override
index 6e0bd75359755e301280813572606a9c6680356d..f459f595a9b4423b928f520d802d791bec30ad3d 100644 (file)
@@ -7,12 +7,17 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
+import static com.google.common.base.Verify.verify;
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement;
@@ -41,7 +46,10 @@ public abstract class AbstractSchemaEffectiveDocumentedNode<A, D extends Declare
     protected AbstractSchemaEffectiveDocumentedNode(final StmtContext<A, D, ?> ctx) {
         super(ctx);
 
-        if (this instanceof SchemaTreeAwareEffectiveStatement) {
+        // This check is rather weird, but comes from our desire to lower memory footprint while providing both
+        // EffectiveStatements and SchemaNode interfaces -- which do not overlap completely where child lookups are
+        // concerned. This ensures that we have SchemaTree index available for use with child lookups.
+        if (this instanceof SchemaTreeAwareEffectiveStatement || this instanceof DataNodeContainer) {
             final StatementSourceReference ref = ctx.getStatementSourceReference();
             final Map<QName, SchemaTreeEffectiveStatement<?>> schemaChildren = new LinkedHashMap<>();
             streamEffectiveSubstatements(SchemaTreeEffectiveStatement.class).forEach(child -> {
@@ -90,6 +98,16 @@ public abstract class AbstractSchemaEffectiveDocumentedNode<A, D extends Declare
         return super.getNamespaceContents(namespace);
     }
 
+    /**
+     * Indexing support for {@link DataNodeContainer#findDataChildByName(QName)}.
+     */
+    protected final Optional<DataSchemaNode> findDataSchemaNode(final QName name) {
+        // Only DataNodeContainer subclasses should be calling this method
+        verify(this instanceof DataNodeContainer);
+        final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace.get(requireNonNull(name));
+        return child instanceof DataSchemaNode ? Optional.of((DataSchemaNode) child) : Optional.empty();
+    }
+
     private static <T extends SchemaTreeEffectiveStatement<?>> void putChild(final Map<QName, T> map,
             final T child, final StatementSourceReference ref, final String tree) {
         final QName id = child.getIdentifier();