Optimize isConfiguration()/isIgnoringConfig() interplay 66/87166/2
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 25 Jan 2020 10:29:21 +0000 (11:29 +0100)
committerRobert Varga <nite@hq.sk>
Mon, 27 Jan 2020 12:50:05 +0000 (12:50 +0000)
Now that we have coalesced these two states into a flag field,
their interplay is more apparent -- isIgnoringConfig() is always
checked before isConfiguration() and if it is set, it also implies
isConfiguration() is also set.

Using flags allows us to express this implication by simply setting
the right bits. This results in fewer flag operations performed and
a more direct dispatch between methods.

isConfiguration() is also improved to access parent.isConfiguration()
only when necessary, improving performance when a config substatement
is present.

JIRA: YANGTOOLS-652
Change-Id: Ifb18ee16e33e93de4300cc80e4ba67a9ae40bbde
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java

index daa1d68e0ecb7bbab0b5bbbc44c0dcd90b81fa01..b59e45153a1a6e986910a054fb0324b1b6c5b187 100644 (file)
@@ -102,17 +102,19 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     // Flag bit assignments
     private static final int IS_SUPPORTED_BY_FEATURES    = 0x01;
     private static final int HAVE_SUPPORTED_BY_FEATURES  = 0x02;
-    private static final int IS_CONFIGURATION            = 0x04;
-    private static final int HAVE_CONFIGURATION          = 0x08;
+    private static final int IS_IGNORE_IF_FEATURE        = 0x04;
+    private static final int HAVE_IGNORE_IF_FEATURE      = 0x08;
+    // Note: these four are related
     private static final int IS_IGNORE_CONFIG            = 0x10;
     private static final int HAVE_IGNORE_CONFIG          = 0x20;
-    private static final int IS_IGNORE_IF_FEATURE        = 0x40;
-    private static final int HAVE_IGNORE_IF_FEATURE      = 0x80;
+    private static final int IS_CONFIGURATION            = 0x40;
+    private static final int HAVE_CONFIGURATION          = 0x80;
 
     // Have-and-set flag constants, also used as masks
     private static final int SET_SUPPORTED_BY_FEATURES = HAVE_SUPPORTED_BY_FEATURES | IS_SUPPORTED_BY_FEATURES;
     private static final int SET_CONFIGURATION = HAVE_CONFIGURATION | IS_CONFIGURATION;
-    private static final int SET_IGNORE_CONFIG = HAVE_IGNORE_CONFIG | IS_IGNORE_CONFIG;
+    // Note: implies SET_CONFIGURATION, allowing fewer bit operations to be performed
+    private static final int SET_IGNORE_CONFIG = HAVE_IGNORE_CONFIG | IS_IGNORE_CONFIG | SET_CONFIGURATION;
     private static final int SET_IGNORE_IF_FEATURE = HAVE_IGNORE_IF_FEATURE | IS_IGNORE_IF_FEATURE;
 
     private final @NonNull StatementDefinitionContext<A, D, E> definition;
@@ -862,29 +864,34 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
      * <p>
      * This method maintains a resolution cache, so once we have returned a result, we will keep on returning the same
      * result without performing any lookups, solely to support {@link SubstatementContext#isConfiguration()}.
+     *
+     * <p>
+     * Note: use of this method implies that {@link #isIgnoringConfig()} is realized with
+     *       {@link #isIgnoringConfig(StatementContextBase)}.
      */
     final boolean isConfiguration(final StatementContextBase<?, ?, ?> parent) {
-        if (isIgnoringConfig()) {
-            return true;
-        }
         final int fl = flags & SET_CONFIGURATION;
         if (fl != 0) {
             return fl == SET_CONFIGURATION;
         }
+        if (isIgnoringConfig(parent)) {
+            // Note: SET_CONFIGURATION has been stored in flags
+            return true;
+        }
+
         final StmtContext<Boolean, ?, ?> configStatement = StmtContextUtils.findFirstSubstatement(this,
             ConfigStatement.class);
-        final boolean parentIsConfig = parent.isConfiguration();
-
         final boolean isConfig;
         if (configStatement != null) {
             isConfig = configStatement.coerceStatementArgument();
-
-            // Validity check: if parent is config=false this cannot be a config=true
-            InferenceException.throwIf(isConfig && !parentIsConfig, getStatementSourceReference(),
-                    "Parent node has config=false, this node must not be specifed as config=true");
+            if (isConfig) {
+                // Validity check: if parent is config=false this cannot be a config=true
+                InferenceException.throwIf(!parent.isConfiguration(), getStatementSourceReference(),
+                        "Parent node has config=false, this node must not be specifed as config=true");
+            }
         } else {
             // If "config" statement is not specified, the default is the same as the parent's "config" value.
-            isConfig = parentIsConfig;
+            isConfig = parent.isConfiguration();
         }
 
         // Resolved, make sure we cache this return
@@ -898,6 +905,10 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
      * This method maintains a resolution cache for ignore config, so once we have returned a result, we will
      * keep on returning the same result without performing any lookups. Exists only to support
      * {@link SubstatementContext#isIgnoringConfig()}.
+     *
+     * <p>
+     * Note: use of this method implies that {@link #isConfiguration()} is realized with
+     *       {@link #isConfiguration(StatementContextBase)}.
      */
     final boolean isIgnoringConfig(final StatementContextBase<?, ?, ?> parent) {
         final int fl = flags & SET_IGNORE_CONFIG;