Compute mustConstraints lazily 62/85962/11
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 25 Nov 2019 14:40:50 +0000 (15:40 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 27 Nov 2019 00:55:55 +0000 (01:55 +0100)
We usually do not access unknown nodes (which are mostly empty
anyway). This patch moves their computation to first access.

JIRA: YANGTOOLS-1041
Change-Id: Idd47d93bd2cfd05816d311e3d9271b6173b2faad
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveMustConstraintAwareDataSchemaNode.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveMustConstraintAwareSimpleDataNodeContainer.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractSchemaEffectiveDocumentedNode.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/NotificationEffectiveStatementImpl.java

index 794a7faa981e31c597d3b9e5c093b059d3756a4e..12226f34b52d5f8648aa6918fb130a87ab1d3eaf 100644 (file)
@@ -9,7 +9,8 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableSet;
-import org.eclipse.jdt.annotation.NonNull;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.MustConstraintAware;
 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
@@ -19,15 +20,26 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 @Beta
 public abstract class AbstractEffectiveMustConstraintAwareDataSchemaNode<D extends DeclaredStatement<QName>>
         extends AbstractEffectiveDataSchemaNode<D> implements MustConstraintAware {
-    private final @NonNull ImmutableSet<MustDefinition> mustConstraints;
+    private static final VarHandle MUST_CONSTRAINTS;
+
+    static {
+        try {
+            MUST_CONSTRAINTS = MethodHandles.lookup().findVarHandle(
+                AbstractEffectiveMustConstraintAwareDataSchemaNode.class, "mustConstraints", ImmutableSet.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private volatile ImmutableSet<MustDefinition> mustConstraints;
 
     protected AbstractEffectiveMustConstraintAwareDataSchemaNode(final StmtContext<QName, D, ?> ctx) {
         super(ctx);
-        mustConstraints = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
     }
 
     @Override
     public final ImmutableSet<MustDefinition> getMustConstraints() {
-        return mustConstraints;
+        return derivedSet(MUST_CONSTRAINTS, MustDefinition.class);
     }
 }
index 8b77221d431670f4b4f7938fe7614b1c66d418fb..58e50985a14335944f2bafeadeb8b856ca107691 100644 (file)
@@ -9,7 +9,8 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableSet;
-import org.eclipse.jdt.annotation.NonNull;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.MustConstraintAware;
 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
@@ -19,15 +20,27 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 @Beta
 public abstract class AbstractEffectiveMustConstraintAwareSimpleDataNodeContainer<D extends DeclaredStatement<QName>>
         extends AbstractEffectiveSimpleDataNodeContainer<D> implements MustConstraintAware {
-    private final @NonNull ImmutableSet<MustDefinition> mustConstraints;
+    private static final VarHandle MUST_CONSTRAINTS;
+
+    static {
+        try {
+            MUST_CONSTRAINTS = MethodHandles.lookup().findVarHandle(
+                AbstractEffectiveMustConstraintAwareSimpleDataNodeContainer.class, "mustConstraints",
+                ImmutableSet.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private volatile ImmutableSet<MustDefinition> mustConstraints;
 
     protected AbstractEffectiveMustConstraintAwareSimpleDataNodeContainer(final StmtContext<QName, D, ?> ctx) {
         super(ctx);
-        mustConstraints = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
     }
 
     @Override
     public final ImmutableSet<MustDefinition> getMustConstraints() {
-        return mustConstraints;
+        return derivedSet(MUST_CONSTRAINTS, MustDefinition.class);
     }
 }
index 6e0bd75359755e301280813572606a9c6680356d..a192f890459cb2bcde6a5fc4aff3d19cfea1e8f4 100644 (file)
@@ -9,9 +9,12 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.lang.invoke.VarHandle;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
@@ -90,6 +93,18 @@ public abstract class AbstractSchemaEffectiveDocumentedNode<A, D extends Declare
         return super.getNamespaceContents(namespace);
     }
 
+    protected final <T> @NonNull ImmutableSet<T> derivedSet(final VarHandle vh, final @NonNull Class<T> clazz) {
+        final ImmutableSet<T> existing = (ImmutableSet<T>) vh.getAcquire(this);
+        return existing != null ? existing : loadSet(vh, clazz);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> @NonNull ImmutableSet<T> loadSet(final VarHandle vh, final @NonNull Class<T> clazz) {
+        final ImmutableSet<T> computed = ImmutableSet.copyOf(allSubstatementsOfType(clazz));
+        final Object witness = vh.compareAndExchangeRelease(this, null, computed);
+        return witness == null ? computed : (ImmutableSet<T>) witness;
+    }
+
     private static <T extends SchemaTreeEffectiveStatement<?>> void putChild(final Map<QName, T> map,
             final T child, final StatementSourceReference ref, final String tree) {
         final QName id = child.getIdentifier();
index 477806ae9f7f26f821dc0e3c71092e84efb7c765..5a198a07023c634a7153b86187f44d32e75c0a9f 100644 (file)
@@ -8,7 +8,8 @@
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification;
 
 import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import java.util.LinkedHashSet;
 import java.util.Objects;
 import java.util.Set;
@@ -29,12 +30,25 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 final class NotificationEffectiveStatementImpl
         extends AbstractEffectiveDocumentedDataNodeContainer<QName, NotificationStatement>
         implements NotificationDefinition, NotificationEffectiveStatement {
+    private static final VarHandle MUST_CONSTRAINTS;
+
+    static {
+        try {
+            MUST_CONSTRAINTS = MethodHandles.lookup().findVarHandle(
+                NotificationEffectiveStatementImpl.class, "mustConstraints", ImmutableSet.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
     private final @NonNull QName qname;
     private final @NonNull SchemaPath path;
     private final ImmutableSet<AugmentationSchemaNode> augmentations;
     private final boolean augmenting;
     private final boolean addedByUses;
-    private final ImmutableSet<MustDefinition> mustConstraints;
+
+    @SuppressWarnings("unused")
+    private volatile ImmutableSet<MustDefinition> mustConstraints;
 
     NotificationEffectiveStatementImpl(
             final StmtContext<QName, NotificationStatement, EffectiveStatement<QName, NotificationStatement>> ctx) {
@@ -51,7 +65,6 @@ final class NotificationEffectiveStatementImpl
             }
         }
         this.augmentations = ImmutableSet.copyOf(augmentationsInit);
-        this.mustConstraints = ImmutableSet.copyOf(this.allSubstatementsOfType(MustDefinition.class));
 
         // initCopyType
         final CopyHistory copyTypesFromOriginal = ctx.getCopyHistory();
@@ -75,8 +88,8 @@ final class NotificationEffectiveStatementImpl
     }
 
     @Override
-    public Collection<MustDefinition> getMustConstraints() {
-        return mustConstraints;
+    public ImmutableSet<MustDefinition> getMustConstraints() {
+        return derivedSet(MUST_CONSTRAINTS, MustDefinition.class);
     }
 
     @Override