Move declaredInstance out of StatementContextBase 92/87292/1
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 28 Jan 2020 18:27:17 +0000 (19:27 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 30 Jan 2020 10:42:17 +0000 (11:42 +0100)
This caching field is useful, except it is clear that only the
original instance really needs it, as InferredStatementContext
will just walk through prototype to acquire it from there.

Move the field into AbstractResumedStatement, i.e.
originally-declared statements, taking buildDeclared() method
implementation there.

This reduces the size of StatementContextBase by one reference
field, which helps InferredStatementContext, as it can now hold
pointer to the original context without increasing object size.

Having the original context allows us to more efficiently shortcut
to the original definition -- which is useful for other methods
as well.

JIRA: YANGTOOLS-784
Change-Id: Ib8767a892b8c8aaa0e3f7da10ac794167269fff6
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 4159f31b29b342181a5e19b3732b36954592a8a8)
(cherry picked from commit 309569041fb3a539ea7683729e357197956f0d8a)

yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/AbstractResumedStatement.java
yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java
yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java

index 7c7f0db7b66b956d6d14559bd57015efe449d5bb..db3202a522806c1a98f16f6750aaed150a1ed5f9 100644 (file)
@@ -13,6 +13,7 @@ import static java.util.Objects.requireNonNull;
 import java.util.Collection;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 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;
@@ -39,6 +40,7 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
     private final String rawArgument;
 
     private StatementMap substatements = StatementMap.empty();
+    private @Nullable D declaredInstance;
 
     // Copy constructor
     AbstractResumedStatement(final AbstractResumedStatement<A, D, E> original) {
@@ -46,6 +48,7 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         this.statementDeclSource = original.statementDeclSource;
         this.rawArgument = original.rawArgument;
         this.substatements = original.substatements;
+        this.declaredInstance = original.declaredInstance;
     }
 
     AbstractResumedStatement(final StatementDefinitionContext<A, D, E> def, final StatementSourceReference ref,
@@ -87,6 +90,18 @@ abstract class AbstractResumedStatement<A, D extends DeclaredStatement<A>, E ext
         return substatements.values();
     }
 
+    @Override
+    public final D buildDeclared() {
+        final D existing = declaredInstance;
+        if (existing != null) {
+            return existing;
+        }
+        final ModelProcessingPhase phase = getCompletedPhase();
+        checkState(phase == ModelProcessingPhase.FULL_DECLARATION || phase == ModelProcessingPhase.EFFECTIVE_MODEL,
+                "Cannot build declared instance after phase %s", phase);
+        return declaredInstance = definition().getFactory().createDeclared(this);
+    }
+
     @Override
     public @NonNull StatementDefinition getDefinition() {
         return getPublicDefinition();
index 3378efde40672533c8d141c404202f355a72448a..1d7a0578051278bea909131d7afcaf0d31745702 100644 (file)
@@ -43,6 +43,7 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
 
     private final @NonNull StatementContextBase<A, D, E> prototype;
     private final @NonNull StatementContextBase<?, ?, ?> parent;
+    private final @NonNull StmtContext<A, D, E> originalCtx;
     private final @NonNull CopyType childCopyType;
     private final QNameModule targetModule;
     private final A argument;
@@ -54,6 +55,7 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
         this.childCopyType = original.childCopyType;
         this.targetModule = original.targetModule;
         this.prototype = original.prototype;
+        this.originalCtx = original.originalCtx;
         this.argument = original.argument;
     }
 
@@ -66,6 +68,8 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
                 : prototype.definition().adaptArgumentValue(prototype, targetModule);
         this.childCopyType = requireNonNull(childCopyType);
         this.targetModule = targetModule;
+        // FIXME: 5.0.0: ugly cast due getOriginalCtx() return type :(
+        this.originalCtx = (StmtContext<A, D, E>) prototype.getOriginalCtx().orElse(prototype);
 
         // FIXME: YANGTOOLS-784: instantiate these lazily
         addEffectiveSubstatements(createEffective());
@@ -90,18 +94,17 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
 
     @Override
     public StatementSourceReference getStatementSourceReference() {
-        return prototype.getStatementSourceReference();
+        return originalCtx.getStatementSourceReference();
     }
 
     @Override
     public String rawStatementArgument() {
-        return prototype.rawStatementArgument();
+        return originalCtx.rawStatementArgument();
     }
 
     @Override
     public Optional<StmtContext<?, ?, ?>> getOriginalCtx() {
-        final Optional<StmtContext<?, ?, ?>> orig = prototype.getOriginalCtx();
-        return orig.isPresent() ? orig : Optional.of(prototype);
+        return Optional.of(originalCtx);
     }
 
     @Override
@@ -110,8 +113,12 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
     }
 
     @Override
-    D createDeclared() {
-        return prototype.buildDeclared();
+    public D buildDeclared() {
+        /*
+         * Share original instance of declared statement between all effective statements which have been copied or
+         * derived from this original declared statement.
+         */
+        return originalCtx.buildDeclared();
     }
 
     @Override
index c5e676aa4a134507b7af34f27d105209b7f7104f..0ee59976f49327045315c6bf8ee7cf4285cfaed7 100644 (file)
@@ -144,7 +144,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     private List<StmtContext<?, ?, ?>> effectOfStatement = ImmutableList.of();
 
     private @Nullable ModelProcessingPhase completedPhase;
-    private @Nullable D declaredInstance;
     private @Nullable E effectiveInstance;
 
     // Master flag controlling whether this context can yield an effective statement
@@ -171,7 +170,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         this.isSupportedToBuildEffective = original.isSupportedToBuildEffective;
         this.fullyDefined = original.fullyDefined;
         this.completedPhase = original.completedPhase;
-        this.declaredInstance = original.declaredInstance;
         this.flags = original.flags;
     }
 
@@ -516,21 +514,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         fullyDefined = true;
     }
 
-    @Override
-    public D buildDeclared() {
-        final D existing = declaredInstance;
-        if (existing != null) {
-            return existing;
-        }
-        checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION
-                || completedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
-        return declaredInstance = createDeclared();
-    }
-
-    @NonNull D createDeclared() {
-        return definition.getFactory().createDeclared(this);
-    }
-
     @Override
     public E buildEffective() {
         final E existing = effectiveInstance;
index 6ce51ab3a21478a96adcfb7b246427339e7fe696..b3d1a69876a7a96fb26eaf20e75f37febafe574b 100644 (file)
@@ -190,6 +190,7 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
      *
      * @return Original definition, if this statement was copied.
      */
+    // FIXME: 5.0.0: this should return Optional<? extends StmtContext<A, D, E>>, is that feasible?
     Optional<StmtContext<?, ?, ?>> getOriginalCtx();
 
     /**
@@ -198,6 +199,7 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
      *
      * @return Context of the previous copy of this statement, if this statement has been copied.
      */
+    // FIXME: 5.0.0: this should return Optional<? extends StmtContext<A, D, E>>
     Optional<? extends StmtContext<?, ?, ?>> getPreviousCopyCtx();
 
     ModelProcessingPhase getCompletedPhase();