From fc9cc1b7980a47ae746d51f28e3a2bca5a007545 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 2 Dec 2020 15:43:35 +0100 Subject: [PATCH] Trim down ReplicaStatementContext Shuffle around the code and class hierarchy to make ReplicaStatementContext inherit only ReactorStmtCtx. This reduces the size of the instance by about one half. JIRA: YANGTOOLS-1184 Change-Id: Ibefc13a6302dd5799839af45bf47e26d232fb563 Signed-off-by: Robert Varga --- .../reactor/AbstractResumedStatement.java | 4 +- .../reactor/InferredStatementContext.java | 32 ++++----- .../parser/stmt/reactor/ReactorStmtCtx.java | 15 ++++ .../stmt/reactor/ReplicaStatementContext.java | 61 ++++++++++------ .../stmt/reactor/StatementContextBase.java | 70 ++++++++----------- .../stmt/action/ActionStatementSupport.java | 2 + .../stmt/rpc/AbstractRpcStatementSupport.java | 2 + 7 files changed, 105 insertions(+), 81 deletions(-) diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java index 194f61f0ce..646ea11218 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java @@ -46,7 +46,7 @@ abstract class AbstractResumedStatement, E ext private final @NonNull StatementSourceReference statementDeclSource; private final String rawArgument; - private List> effective = ImmutableList.of(); + private List> effective = ImmutableList.of(); private StatementMap substatements = StatementMap.empty(); private @Nullable D declaredInstance; @@ -192,7 +192,7 @@ abstract class AbstractResumedStatement, E ext } @Override - final Iterable> effectiveChildrenToComplete() { + final Iterable> effectiveChildrenToComplete() { return effective; } diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java index 9de44e07c8..b3f7278a88 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java @@ -258,14 +258,14 @@ final class InferredStatementContext, E extend // Instantiate this statement's effective substatements. Note this method has side-effects in namespaces and overall // BuildGlobalContext, hence it must be called at most once. - private List> ensureEffectiveSubstatements() { + private List> ensureEffectiveSubstatements() { accessSubstatements(); return substatements instanceof List ? castEffective(substatements) : initializeSubstatements(castMaterialized(substatements)); } @Override - Iterable> effectiveChildrenToComplete() { + Iterable> effectiveChildrenToComplete() { // When we have not initialized, there are no statements to catch up: we will catch up when we are copying // from prototype (which is already at ModelProcessingPhase.EFFECTIVE_MODEL). if (substatements == null) { @@ -300,15 +300,15 @@ final class InferredStatementContext, E extend substatements = SWEPT_SUBSTATEMENTS; int count = 0; if (local != null) { - final List> list = castEffective(local); + final List> list = castEffective(local); sweep(list); count = countUnswept(list); } return count; } - private List> initializeSubstatements( - final Map, StatementContextBase> materializedSchemaTree) { + private List> initializeSubstatements( + final Map, ReactorStmtCtx> materializedSchemaTree) { final Collection> declared = prototype.mutableDeclaredSubstatements(); final Collection> effective = prototype.mutableEffectiveSubstatements(); @@ -322,8 +322,7 @@ final class InferredStatementContext, E extend copySubstatement(stmtContext, buffer, materializedSchemaTree); } - final List> ret = beforeAddEffectiveStatementUnsafe(ImmutableList.of(), - buffer.size()); + final List> ret = beforeAddEffectiveStatementUnsafe(ImmutableList.of(), buffer.size()); ret.addAll((Collection) buffer); substatements = ret; @@ -343,7 +342,7 @@ final class InferredStatementContext, E extend YangStmtMapping.USES); private void copySubstatement(final Mutable substatement, final Collection> buffer, - final Map, StatementContextBase> materializedSchemaTree) { + final Map, ReactorStmtCtx> materializedSchemaTree) { final StatementDefinition def = substatement.publicDefinition(); // FIXME: YANGTOOLS-652: formerly known as "isReusedByUses" @@ -358,7 +357,7 @@ final class InferredStatementContext, E extend // // We could also perform a Map.containsKey() and perform a bulk add, but that would mean the statement order // against parent would change -- and we certainly do not want that to happen. - final StatementContextBase materialized = findMaterialized(materializedSchemaTree, substatement); + final ReactorStmtCtx materialized = findMaterialized(materializedSchemaTree, substatement); if (materialized == null) { copySubstatement(substatement).ifPresent(copy -> { ensureCompletedPhase(copy); @@ -374,7 +373,7 @@ final class InferredStatementContext, E extend } private void addMaterialized(final StmtContext template, final Mutable copy) { - final HashMap, StatementContextBase> materializedSchemaTree; + final HashMap, ReactorStmtCtx> materializedSchemaTree; if (substatements == null) { // Lazy initialization of backing map. We do not expect this to be used often or multiple times -- each hit // here means an inference along schema tree, such as deviate/augment. HashMap requires power-of-two and @@ -395,21 +394,20 @@ final class InferredStatementContext, E extend } } - private static @Nullable StatementContextBase findMaterialized( - final Map, StatementContextBase> materializedSchemaTree, + private static @Nullable ReactorStmtCtx findMaterialized( + final Map, ReactorStmtCtx> materializedSchemaTree, final StmtContext template) { return materializedSchemaTree == null ? null : materializedSchemaTree.get(template); } @SuppressWarnings("unchecked") - private static List> castEffective(final Object substatements) { - return (List>) substatements; + private static List> castEffective(final Object substatements) { + return (List>) substatements; } @SuppressWarnings("unchecked") - private static HashMap, StatementContextBase> castMaterialized( - final Object substatements) { - return (HashMap, StatementContextBase>) substatements; + private static HashMap, ReactorStmtCtx> castMaterialized(final Object substatements) { + return (HashMap, ReactorStmtCtx>) substatements; } // Statement copy mess ends here diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java index e4b0dd37a2..b3d9dd7848 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReactorStmtCtx.java @@ -42,6 +42,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Regist import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace; import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace.SupportedFeatures; import org.slf4j.Logger; @@ -320,6 +321,20 @@ abstract class ReactorStmtCtx, E extends Effec abstract @NonNull E createEffective(); + /** + * Try to execute current {@link ModelProcessingPhase} of source parsing. If the phase has already been executed, + * this method does nothing. + * + * @param phase to be executed (completed) + * @return true if phase was successfully completed + * @throws SourceException when an error occurred in source parsing + */ + final boolean tryToCompletePhase(final ModelProcessingPhase phase) { + return phase.isCompletedBy(getCompletedPhase()) || doTryToCompletePhase(phase); + } + + abstract boolean doTryToCompletePhase(ModelProcessingPhase phase); + // // // Flags-based mechanics. These include public interfaces as well as all the crud we have lurking in our alignment diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java index 071b73b37a..173e9315ba 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ReplicaStatementContext.java @@ -9,15 +9,19 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import static java.util.Objects.requireNonNull; -import com.google.common.collect.ImmutableList; import java.util.Collection; import java.util.Optional; -import java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; +import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; +import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; @@ -26,11 +30,11 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReferenc * designated source. */ final class ReplicaStatementContext, E extends EffectiveStatement> - extends StatementContextBase { + extends ReactorStmtCtx { private final StatementContextBase parent; - private final StatementContextBase source; + private final ReactorStmtCtx source; - ReplicaStatementContext(final StatementContextBase parent, final StatementContextBase source) { + ReplicaStatementContext(final StatementContextBase parent, final ReactorStmtCtx source) { super(source); this.parent = requireNonNull(parent); this.source = requireNonNull(source); @@ -88,13 +92,29 @@ final class ReplicaStatementContext, E extends } @Override - boolean hasEmptySubstatements() { - return source.hasEmptySubstatements(); + public ModelProcessingPhase getCompletedPhase() { + return source.getCompletedPhase(); } @Override - Iterable> effectiveChildrenToComplete() { - return ImmutableList.of(); + public CopyHistory history() { + return source.history(); + } + + @Override + public Mutable replicaAsChildOf(final Mutable newParent) { + return source.replicaAsChildOf(newParent); + } + + @Override + public Optional> copyAsChildOf(final Mutable newParent, final CopyType type, + final QNameModule targetModule) { + return source.copyAsChildOf(newParent, type, targetModule); + } + + @Override + StatementDefinitionContext definition() { + return source.definition(); } @Override @@ -106,43 +126,44 @@ final class ReplicaStatementContext, E extends } @Override - public Optional> getPreviousCopyCtx() { + public > void addToNs( + final Class<@NonNull N> type, final T key, final U value) { throw new UnsupportedOperationException(); } @Override - public void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef) { + public Optional> getPreviousCopyCtx() { throw new UnsupportedOperationException(); } @Override - public void removeStatementFromEffectiveSubstatements(final StatementDefinition statementDef, - final String statementArg) { + public > void addContext(final Class<@NonNull N> namespace, + final KT key, final StmtContext stmt) { throw new UnsupportedOperationException(); } @Override - public void addEffectiveSubstatement(final Mutable substatement) { + public void addAsEffectOfStatement(final StmtContext ctx) { throw new UnsupportedOperationException(); } @Override - void addEffectiveSubstatementsImpl(final Collection> statements) { + public void addAsEffectOfStatement(final Collection> ctxs) { throw new UnsupportedOperationException(); } @Override - Stream> streamDeclared() { + public Collection> getEffectOfStatement() { throw new UnsupportedOperationException(); } @Override - Stream> streamEffective() { + public Mutable childCopyOf(final StmtContext stmt, final CopyType type, + final QNameModule targetModule) { throw new UnsupportedOperationException(); } - @Override - StatementContextBase reparent(final StatementContextBase newParent) { + @Override boolean doTryToCompletePhase(final ModelProcessingPhase phase) { throw new UnsupportedOperationException(); } diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index 46697255a8..6903620c32 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -149,12 +149,12 @@ public abstract class StatementContextBase, E } @Override - public CopyHistory history() { + public final CopyHistory history() { return copyHistory; } @Override - public ModelProcessingPhase getCompletedPhase() { + public final ModelProcessingPhase getCompletedPhase() { return completedPhase; } @@ -171,19 +171,18 @@ public abstract class StatementContextBase, E } static final Collection> mutableEffectiveSubstatements( - final List> effective) { + final List> effective) { return effective instanceof ImmutableCollection ? effective : Collections.unmodifiableCollection(effective); } - private static List> shrinkEffective( - final List> effective) { + private static List> shrinkEffective(final List> effective) { return effective.isEmpty() ? ImmutableList.of() : effective; } public abstract void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef); - static final List> removeStatementFromEffectiveSubstatements( - final List> effective, final StatementDefinition statementDef) { + static final List> removeStatementFromEffectiveSubstatements( + final List> effective, final StatementDefinition statementDef) { if (effective.isEmpty()) { return effective; } @@ -214,8 +213,8 @@ public abstract class StatementContextBase, E public abstract void removeStatementFromEffectiveSubstatements(StatementDefinition statementDef, String statementArg); - static final List> removeStatementFromEffectiveSubstatements( - final List> effective, final StatementDefinition statementDef, + static final List> removeStatementFromEffectiveSubstatements( + final List> effective, final StatementDefinition statementDef, final String statementArg) { if (statementArg == null) { return removeStatementFromEffectiveSubstatements(effective, statementDef); @@ -225,7 +224,7 @@ public abstract class StatementContextBase, E return effective; } - final Iterator> iterator = effective.iterator(); + final Iterator> iterator = effective.iterator(); while (iterator.hasNext()) { final Mutable next = iterator.next(); if (statementDef.equals(next.publicDefinition()) && statementArg.equals(next.rawArgument())) { @@ -258,12 +257,12 @@ public abstract class StatementContextBase, E */ public abstract void addEffectiveSubstatement(Mutable substatement); - final List> addEffectiveSubstatement( - final List> effective, final Mutable substatement) { + final List> addEffectiveSubstatement(final List> effective, + final Mutable substatement) { verifyStatement(substatement); - final List> resized = beforeAddEffectiveStatement(effective, 1); - final StatementContextBase stmt = (StatementContextBase) substatement; + final List> resized = beforeAddEffectiveStatement(effective, 1); + final ReactorStmtCtx stmt = (ReactorStmtCtx) substatement; final ModelProcessingPhase phase = completedPhase; if (phase != null) { ensureCompletedPhase(stmt, phase); @@ -290,10 +289,9 @@ public abstract class StatementContextBase, E abstract void addEffectiveSubstatementsImpl(Collection> statements); - final List> addEffectiveSubstatementsImpl( - final List> effective, + final List> addEffectiveSubstatementsImpl(final List> effective, final Collection> statements) { - final List> resized = beforeAddEffectiveStatement(effective, statements.size()); + final List> resized = beforeAddEffectiveStatement(effective, statements.size()); final Collection> casted = (Collection>) statements; final ModelProcessingPhase phase = completedPhase; @@ -307,39 +305,38 @@ public abstract class StatementContextBase, E return resized; } - abstract Iterable> effectiveChildrenToComplete(); + abstract Iterable> effectiveChildrenToComplete(); // exposed for InferredStatementContext only final void ensureCompletedPhase(final Mutable stmt) { verifyStatement(stmt); final ModelProcessingPhase phase = completedPhase; if (phase != null) { - ensureCompletedPhase((StatementContextBase) stmt, phase); + ensureCompletedPhase((ReactorStmtCtx) stmt, phase); } } // Make sure target statement has transitioned at least to specified phase. This method is just before we take // allow a statement to become our substatement. This is needed to ensure that every statement tree does not contain // any statements which did not complete the same phase as the root statement. - private static void ensureCompletedPhase(final StatementContextBase stmt, - final ModelProcessingPhase phase) { + private static void ensureCompletedPhase(final ReactorStmtCtx stmt, final ModelProcessingPhase phase) { verify(stmt.tryToCompletePhase(phase), "Statement %s cannot complete phase %s", stmt, phase); } private static void verifyStatement(final Mutable stmt) { - verify(stmt instanceof StatementContextBase, "Unexpected statement %s", stmt); + verify(stmt instanceof ReactorStmtCtx, "Unexpected statement %s", stmt); } - private List> beforeAddEffectiveStatement( - final List> effective, final int toAdd) { + private List> beforeAddEffectiveStatement(final List> effective, + final int toAdd) { // We cannot allow statement to be further mutated verify(completedPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Cannot modify finished statement at %s", sourceReference()); return beforeAddEffectiveStatementUnsafe(effective, toAdd); } - final List> beforeAddEffectiveStatementUnsafe( - final List> effective, final int toAdd) { + final List> beforeAddEffectiveStatementUnsafe(final List> effective, + final int toAdd) { final ModelProcessingPhase inProgressPhase = getRoot().getSourceContext().getInProgressPhase(); checkState(inProgressPhase == ModelProcessingPhase.FULL_DECLARATION || inProgressPhase == ModelProcessingPhase.EFFECTIVE_MODEL, @@ -358,19 +355,8 @@ public abstract class StatementContextBase, E abstract Stream> streamEffective(); - /** - * Try to execute current {@link ModelProcessingPhase} of source parsing. If the phase has already been executed, - * this method does nothing. - * - * @param phase to be executed (completed) - * @return true if phase was successfully completed - * @throws SourceException when an error occurred in source parsing - */ - final boolean tryToCompletePhase(final ModelProcessingPhase phase) { - return phase.isCompletedBy(completedPhase) || doTryToCompletePhase(phase); - } - - private boolean doTryToCompletePhase(final ModelProcessingPhase phase) { + @Override + final boolean doTryToCompletePhase(final ModelProcessingPhase phase) { final boolean finished = phaseMutation.isEmpty() ? true : runMutations(phase); if (completeChildren(phase) && finished) { onPhaseCompleted(phase); @@ -384,7 +370,7 @@ public abstract class StatementContextBase, E for (final StatementContextBase child : mutableDeclaredSubstatements()) { finished &= child.tryToCompletePhase(phase); } - for (final StatementContextBase child : effectiveChildrenToComplete()) { + for (final ReactorStmtCtx child : effectiveChildrenToComplete()) { finished &= child.tryToCompletePhase(phase); } return finished; @@ -678,12 +664,12 @@ public abstract class StatementContextBase, E } @Override - public final StatementContextBase replicaAsChildOf(final Mutable parent) { + public final ReactorStmtCtx replicaAsChildOf(final Mutable parent) { checkArgument(parent instanceof StatementContextBase, "Unsupported parent %s", parent); return replicaAsChildOf((StatementContextBase) parent); } - final @NonNull StatementContextBase replicaAsChildOf(final StatementContextBase stmt) { + final @NonNull ReplicaStatementContext replicaAsChildOf(final StatementContextBase stmt) { return new ReplicaStatementContext<>(stmt, this); } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/action/ActionStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/action/ActionStatementSupport.java index 6eb0b1d005..b277bf0256 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/action/ActionStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/action/ActionStatementSupport.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.action; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Verify.verify; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -64,6 +65,7 @@ public final class ActionStatementSupport extends public void onFullDefinitionDeclared(final Mutable stmt) { super.onFullDefinitionDeclared(stmt); + verify(stmt instanceof StatementContextBase); if (StmtContextUtils.findFirstDeclaredSubstatement(stmt, InputStatement.class) == null) { ((StatementContextBase) stmt).appendImplicitSubstatement( InputStatementRFC7950Support.getInstance(), null); diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/rpc/AbstractRpcStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/rpc/AbstractRpcStatementSupport.java index 6760b21818..06909a6cd2 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/rpc/AbstractRpcStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/rpc/AbstractRpcStatementSupport.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.rpc; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Verify.verify; import com.google.common.collect.ImmutableList; import org.opendaylight.yangtools.yang.common.QName; @@ -53,6 +54,7 @@ abstract class AbstractRpcStatementSupport extends BaseSchemaTreeStatementSuppor public final void onFullDefinitionDeclared(final Mutable stmt) { super.onFullDefinitionDeclared(stmt); + verify(stmt instanceof StatementContextBase); if (StmtContextUtils.findFirstDeclaredSubstatement(stmt, InputStatement.class) == null) { ((StatementContextBase) stmt).appendImplicitSubstatement(implictInput(), null); } -- 2.36.6