Optimize isConfiguration()/isIgnoringConfig() interplay 68/87268/1
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 25 Jan 2020 10:29:21 +0000 (11:29 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 29 Jan 2020 16:14:11 +0000 (17:14 +0100)
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>
(cherry picked from commit 7cb2365fa775c4b3026aa77662d34fddbda30b60)

yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java

index 93540bda86a8b36f276274da889807cbc75600e1..8e6d1ea9032c9eb7729b5ce34ece45c070cd1645 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;