Mark statements as context-insensitive 02/87402/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 26 Jan 2020 02:14:54 +0000 (03:14 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 4 Feb 2020 06:59:34 +0000 (07:59 +0100)
A number of statements are subject to inlining, but not all of them
are affected by such inlining.

When a substatement is not affected by inlining (and inference
after the fact), we can safely reuse original statement context for
the purposes of representing effective state.

Teach AbstractStatementSupport about the concept of context-independence
and take advantage of it in simple statements. The end result is
fewer instantiated StmtContext objects, reducing peak memory usage.

Since StmtContext instance are shared, we also end up sharing
EffectiveStatement implementations, completely removing duplication
in reference test case -- eliminating ~3.7M objects and trimming
retained size by 56MiB, i.e. 7.8%.

JIRA: YANGTOOLS-694
Change-Id: I2e29ef24cf31ca800de36403037c3af11698a789
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
17 files changed:
yang/rfc6536-parser-support/src/main/java/org/opendaylight/yangtools/rfc6536/parser/DefaultDenyAllStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseBooleanStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseInternedStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/BaseStringStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/fraction_digits/FractionDigitsStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/if_feature/IfFeatureStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/length/LengthStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/max_elements/MaxElementsStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/pattern/AbstractPatternStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/revision_date/RevisionDateStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/status/StatusStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/yang_version/YangVersionStatementSupport.java
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractVoidStatementSupport.java
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ForwardingStatementSupport.java
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java

index 4f9d096ea2bb96a6247fe666e83085a6cffcf798..32427aea64e163065cb9ada5314f774a0ce215fa 100644 (file)
@@ -62,7 +62,7 @@ public final class DefaultDenyAllStatementSupport
     private final SubstatementValidator validator;
 
     private DefaultDenyAllStatementSupport(final StatementDefinition definition) {
-        super(definition);
+        super(definition, CopyPolicy.CONTEXT_INDEPENDENT);
         this.validator = SubstatementValidator.builder(definition).build();
     }
 
index cddf9376187a6a872bbf99ba254ef9be3b494f44..f0bd696c5c7667c78cad30b17824a1bac53c73eb 100644 (file)
@@ -32,7 +32,7 @@ public abstract class BaseBooleanStatementSupport<D extends DeclaredStatement<Bo
 
     protected BaseBooleanStatementSupport(final StatementDefinition publicDefinition,
             final E emptyEffectiveFalse, final E emptyEffectiveTrue) {
-        super(publicDefinition);
+        super(publicDefinition, CopyPolicy.CONTEXT_INDEPENDENT);
         this.emptyEffectiveFalse = requireNonNull(emptyEffectiveFalse);
         this.emptyEffectiveTrue = requireNonNull(emptyEffectiveTrue);
         emptyDeclaredFalse = requireNonNull(emptyEffectiveFalse.getDeclared());
index 8807020f030577855f3fa9e014a91b049eacc84c..87301fc369e4511c8cda37e0082a58f8967e042d 100644 (file)
@@ -24,6 +24,9 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
  * reasonably interned and it dominates the {@link EffectiveStatement} implementation. Typical examples include
  * {@code position} and {@code value} statements, which typically do not have substatements and are based on simple
  * types.
+ *
+ * <p>
+ * Note: use of this base class implies context-independence.
  */
 @Beta
 public abstract class BaseInternedStatementSupport<A, D extends DeclaredStatement<A>,
@@ -44,7 +47,7 @@ public abstract class BaseInternedStatementSupport<A, D extends DeclaredStatemen
             });
 
     protected BaseInternedStatementSupport(final StatementDefinition publicDefinition) {
-        super(publicDefinition);
+        super(publicDefinition, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     @Override
index 97f64a9975151d223906d5ce95fcb815abda1efb..645e24ce2f8682fff9366cbe174ba58bb7346d57 100644 (file)
@@ -36,6 +36,10 @@ public abstract class BaseStatementSupport<A, D extends DeclaredStatement<A>,
         super(publicDefinition);
     }
 
+    protected BaseStatementSupport(final StatementDefinition publicDefinition, final CopyPolicy copyPolicy) {
+        super(publicDefinition, copyPolicy);
+    }
+
     @Override
     public final D createDeclared(final StmtContext<A, D, ?> ctx) {
         final ImmutableList<? extends DeclaredStatement<?>> substatements = ctx.declaredSubstatements().stream()
index 416579ba63db3e94bcd133d653da44e863e61bee..9c60734930c66ea749e1c14382cbb456f00e681d 100644 (file)
@@ -13,7 +13,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
- * Specialization of {@link BaseStatementSupport} for String statement arguments.
+ * Specialization of {@link BaseStatementSupport} for String statement arguments. Note this implies context-independence
+ * by default.
  *
  * @param <D> Declared Statement representation
  * @param <E> Effective Statement representation
@@ -22,6 +23,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 public abstract class BaseStringStatementSupport<D extends DeclaredStatement<String>,
         E extends EffectiveStatement<String, D>> extends BaseStatementSupport<String, D, E> {
     protected BaseStringStatementSupport(final StatementDefinition publicDefinition) {
-        super(publicDefinition);
+        super(publicDefinition, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 }
index f294c14e24d59bb84a018c15e3cf8e90c1b76fea..ecd260f6df88d2b63b022975807ce9834abe7074 100644 (file)
@@ -48,7 +48,7 @@ public final class FractionDigitsStatementSupport
     }
 
     private FractionDigitsStatementSupport() {
-        super(YangStmtMapping.FRACTION_DIGITS);
+        super(YangStmtMapping.FRACTION_DIGITS, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static FractionDigitsStatementSupport getInstance() {
index 4ead80adc55f005506ab28cdce4ac3ab4b010662..fb952751e98befee97554ba0155d9cb3d1d7ab92 100644 (file)
@@ -44,7 +44,7 @@ public final class IfFeatureStatementSupport
     private static final IfFeatureStatementSupport INSTANCE = new IfFeatureStatementSupport();
 
     private IfFeatureStatementSupport() {
-        super(YangStmtMapping.IF_FEATURE);
+        super(YangStmtMapping.IF_FEATURE, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static IfFeatureStatementSupport getInstance() {
index 55ed75230bee93d34b02eea614404f406f1f8a24..f0e70d29810f4e4595eff48c07966f771ae10294 100644 (file)
@@ -37,7 +37,7 @@ public final class LengthStatementSupport
     private static final LengthStatementSupport INSTANCE = new LengthStatementSupport();
 
     private LengthStatementSupport() {
-        super(YangStmtMapping.LENGTH);
+        super(YangStmtMapping.LENGTH, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static LengthStatementSupport getInstance() {
index 37890c9eafe4c395d5c733f0539d36867ea3af06..b6ff968e21bc093b3b9e3307695e487e280561f3 100644 (file)
@@ -22,7 +22,7 @@ public final class MaxElementsStatementSupport
     private static final MaxElementsStatementSupport INSTANCE = new MaxElementsStatementSupport();
 
     private MaxElementsStatementSupport() {
-        super(YangStmtMapping.MAX_ELEMENTS);
+        super(YangStmtMapping.MAX_ELEMENTS, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static MaxElementsStatementSupport getInstance() {
index 9670200dee0498aee0f23301ad605f2f7671470a..c86acbf641fd375382c19cc8529e7220d1776bb0 100644 (file)
@@ -25,7 +25,7 @@ abstract class AbstractPatternStatementSupport
     private static final Logger LOG = LoggerFactory.getLogger(AbstractPatternStatementSupport.class);
 
     AbstractPatternStatementSupport() {
-        super(YangStmtMapping.PATTERN);
+        super(YangStmtMapping.PATTERN, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     @Override
index 8fa8e7840b1c7e5a454dcf907fa9aadd329f1391..07924d7cb703785b1f0082d7a07fdcae741276f3 100644 (file)
@@ -24,7 +24,7 @@ public final class RevisionDateStatementSupport
     private static final RevisionDateStatementSupport INSTANCE = new RevisionDateStatementSupport();
 
     private RevisionDateStatementSupport() {
-        super(YangStmtMapping.REVISION_DATE);
+        super(YangStmtMapping.REVISION_DATE, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static RevisionDateStatementSupport getInstance() {
index 13f062b99387ab8eb921b35ec2b9523098ef78a0..3d45d44b05edade9e7ceb7c1984ca9ade8ed5672 100644 (file)
@@ -45,7 +45,7 @@ public final class StatusStatementSupport
             new EmptyStatusEffectiveStatement(EMPTY_OBSOLETE_DECL);
 
     private StatusStatementSupport() {
-        super(YangStmtMapping.STATUS);
+        super(YangStmtMapping.STATUS, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static StatusStatementSupport getInstance() {
index 507e5e772b10170c07b5289b749775de541c5656..8e9b291cad1af3f9fb00f3db9f501206c6d050bb 100644 (file)
@@ -38,7 +38,7 @@ public final class YangVersionStatementSupport
             new EmptyYangVersionEffectiveStatement(EMPTY_VER1_1_DECL);
 
     private YangVersionStatementSupport() {
-        super(YangStmtMapping.YANG_VERSION);
+        super(YangStmtMapping.YANG_VERSION, CopyPolicy.CONTEXT_INDEPENDENT);
     }
 
     public static YangVersionStatementSupport getInstance() {
index d8e9c42ee31d6fed3ba3c27a526d5b823f98194d..ee945c90caf908d9edcdcd24f28db8cad591601e 100644 (file)
@@ -10,11 +10,14 @@ package org.opendaylight.yangtools.yang.parser.spi.meta;
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.annotations.Beta;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 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.parser.spi.meta.StmtContext.Mutable;
 
 /**
  * Class providing necessary support for processing a YANG statement. This class is intended to be subclassed
@@ -28,17 +31,30 @@ public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>
         implements StatementDefinition, StatementFactory<A, D, E>, StatementSupport<A, D, E> {
 
     private final @NonNull StatementDefinition type;
+    private final @NonNull CopyPolicy copyPolicy;
 
-    protected AbstractStatementSupport(final StatementDefinition publicDefinition) {
+    @Beta
+    protected AbstractStatementSupport(final StatementDefinition publicDefinition, final CopyPolicy copyPolicy) {
         this.type = requireNonNull(publicDefinition);
+        this.copyPolicy = requireNonNull(copyPolicy);
         checkArgument(publicDefinition != this);
     }
 
+    protected AbstractStatementSupport(final StatementDefinition publicDefinition) {
+        this(publicDefinition, CopyPolicy.DECLARED_COPY);
+    }
+
     @Override
     public final StatementDefinition getPublicView() {
         return type;
     }
 
+    @Override
+    public CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
+            final CopyType copyType, final QNameModule targetModule) {
+        return copyPolicy;
+    }
+
     @Override
     public void onStatementAdded(final StmtContext.Mutable<A, D, E> stmt) {
         // NOOP for most implementations
index 8a3c642049eba3515a03926e1f5414a7776ac54a..be5c7543da94f0284427f12fb579a8f80b2be818 100644 (file)
@@ -27,6 +27,10 @@ public abstract class AbstractVoidStatementSupport<D extends DeclaredStatement<V
         super(publicDefinition);
     }
 
+    protected AbstractVoidStatementSupport(final StatementDefinition publicDefinition, final CopyPolicy copyPolicy) {
+        super(publicDefinition, copyPolicy);
+    }
+
     @Override
     public final Void parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
         return null;
index b8972cf686f0354c0e0cbe08606d8f4434ac69e3..f0c4ff42a5a20428bab12fd4e3debdc7e23f5d29 100644 (file)
@@ -88,8 +88,8 @@ public abstract class ForwardingStatementSupport<A, D extends DeclaredStatement<
     }
 
     @Override
-    public CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt,
-            final Mutable<?, ?, ?> parent, final CopyType type, final QNameModule targetModule) {
-        return delegate().applyCopyPolicy(stmt, parent, type, targetModule);
+    public CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
+            final CopyType copyType, final QNameModule targetModule) {
+        return delegate().applyCopyPolicy(stmt, parent, copyType, targetModule);
     }
 }
index 7aee38118cdefcf022ccd10d97bca0526ca4254a..79658e8fecde0876d1f4a2fbc77c9e64fa3255ba 100644 (file)
@@ -147,13 +147,13 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      *
      * @param stmt Context of statement to be copied statement.
      * @param parent Parent statement context
-     * @param type Type of copy being performed
+     * @param copyType Type of copy being performed
      * @param targetModule Target module, if present
      * @return Policy that needs to be applied to the copy operation of this statement.
      */
     // FIXME: YANGTOOLS-694: clarify targetModule semantics (does null mean 'same as declared'?)
     default @NonNull CopyPolicy applyCopyPolicy(final Mutable<?, ?, ?> stmt, final Mutable<?, ?, ?> parent,
-            final CopyType type, @Nullable final QNameModule targetModule) {
+            final CopyType copyType, @Nullable final QNameModule targetModule) {
         // Most of statement supports will just want to copy the statement
         // FIXME: YANGTOOLS-694: that is not strictly true. Subclasses of this should indicate if they are themselves
         //                       copy-sensitive: