From 7eafc450f8a7c09f9d98c0d4d7608b16588244cb Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 26 Oct 2016 01:24:15 +0200 Subject: [PATCH] BUG-6522: create a dedicated extensions map SourceSpecificContext already calls out to BuildGlobalContext to lookup up support statements, hence the potential extension lookup will be slower. This lookup occurs before we check for type arguments, hence we want to keep it fast. Therefore we take a snapshot of all extensions defined in the global context. Also make StatementDefinitionNamespace a source-local, so the definitions do not leak outside of the module where they are defined. Change-Id: I0c50de89cee5d4297e8ccd0cb61203c3cfe9a2f3 Signed-off-by: Robert Varga --- .../stmt/reactor/SourceSpecificContext.java | 32 ++++++++++++------- .../stmt/rfc6020/YangInferencePipeline.java | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index 1d8c2ac6ed..ec0ae03634 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -11,6 +11,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Multimap; import java.net.URI; import java.util.ArrayList; @@ -82,12 +83,13 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh .put(TypeUtils.INSTANCE_IDENTIFIER, new InstanceIdentifierSpecificationImpl.Definition()) .build(); - private final Multimap modifiers = HashMultimap.create(); private final QNameToStatementDefinitionMap qNameToStmtDefMap = new QNameToStatementDefinitionMap(); + private final Multimap modifiers = HashMultimap.create(); private final PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap(); private final BuildGlobalContext currentContext; private final StatementStreamSource source; + private Map> definedExtensions = ImmutableMap.of(); private Collection importedNamespaces = ImmutableList.of(); private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT; private ModelProcessingPhase inProgressPhase; @@ -111,7 +113,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh StatementDefinitionContext def = currentContext.getStatementDefinition(name); if (def == null) { - final StatementSupport extension = qNameToStmtDefMap.get(name); + final StatementSupport extension = definedExtensions.get(name); if (extension != null) { def = new StatementDefinitionContext<>(extension); } else { @@ -362,20 +364,28 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh return prefixToModuleMap; } + private static void addSupports(final Builder builder, @Nullable final Map supports) { + if (supports != null) { + builder.putAll(supports); + } + } + private QNameToStatementDefinition stmtDef() { // regular YANG statements and extension supports added qNameToStmtDefMap.putAll(currentContext.getSupportsForPhase(inProgressPhase).getDefinitions()); - // No further actions needed - if (inProgressPhase != ModelProcessingPhase.FULL_DECLARATION) { - return qNameToStmtDefMap; - } - // We need to any and all extension statements which have been declared in the context - final Map> extensions = currentContext.getAllFromNamespace( - StatementDefinitionNamespace.class); - if (extensions != null) { - extensions.forEach((qname, support) -> { + if (inProgressPhase == ModelProcessingPhase.FULL_DECLARATION) { + // We maintain this map for createDeclaredChild(), which calls out to global context first, + // hence there is no point in performing double lookups. + final Builder> b = ImmutableMap.builder(); + addSupports(b, getRoot().getAllFromLocalStorage(StatementDefinitionNamespace.class)); + for (NamespaceStorageNode namespace : importedNamespaces) { + addSupports(b, namespace.getAllFromLocalStorage(StatementDefinitionNamespace.class)); + } + + definedExtensions = b.build(); + definedExtensions.forEach((qname, support) -> { final StatementSupport existing = qNameToStmtDefMap.putIfAbsent(qname, support); if (existing != null) { LOG.debug("Source {} already defines statement {} as {}", source, qname, existing); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java index d0802782e9..4bb671e651 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java @@ -144,7 +144,7 @@ public final class YangInferencePipeline { .addSupport(new FractionDigitsStatementImpl.Definition()) .addSupport(new BaseStatementImpl.Definition()) .addSupport(global(DerivedIdentitiesNamespace.class)) - .addSupport(global(StatementDefinitionNamespace.class)) + .addSupport(sourceLocal(StatementDefinitionNamespace.class)) .build(); public static final StatementSupportBundle FULL_DECL_BUNDLE = StatementSupportBundle -- 2.36.6