Adjust LeafEffectiveStatement argument storage 45/98845/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 5 Dec 2021 16:11:45 +0000 (17:11 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 6 Dec 2021 00:02:57 +0000 (01:02 +0100)
For original leaves the argument matches the declared view, hence
we can save a field.

JIRA: YANGTOOLS-1316
Change-Id: I6eb3190ad1fc368faeedd3e2ad60fbbaca526a9f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/EffectiveStatements.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractLeafEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/EmptyLeafEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/RegularLeafEffectiveStatement.java

index 7307a071eb362e896b0e320c2980f3a63499f529..d7edccbeefdf918835a51080a738f999138f9cef 100644 (file)
@@ -565,8 +565,8 @@ public final class EffectiveStatements {
     public static LeafEffectiveStatement createLeaf(final LeafStatement declared, final QName argument, final int flags,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements)
                 throws SubstatementIndexingException {
-        // FIXME: YANGTOOLS-1316: instantiate RegularLeafEffectiveStatement() in argument mismatch
-        return new EmptyLeafEffectiveStatement(declared, argument, flags, substatements);
+        return argument.equals(declared.argument()) ? new EmptyLeafEffectiveStatement(declared, flags, substatements)
+            : new RegularLeafEffectiveStatement(declared, argument, flags, substatements);
     }
 
     public static LeafListEffectiveStatement copyLeafList(final LeafListEffectiveStatement original,
index 08d2598319b3a2b4ea05b5f9725df0632f80e580..856112716b54ff5fbdd36c7b1e8f72ba16c00a97 100644 (file)
@@ -7,9 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.collect.ImmutableList;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
@@ -23,7 +23,6 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatemen
 import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.ri.type.ConcreteTypeBuilder;
 import org.opendaylight.yangtools.yang.model.ri.type.ConcreteTypes;
 import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataSchemaNodeMixin;
@@ -34,31 +33,34 @@ public abstract class AbstractLeafEffectiveStatement
         extends AbstractDeclaredEffectiveStatement.Default<QName, LeafStatement>
         implements LeafEffectiveStatement, LeafSchemaNode, DataSchemaNodeMixin<LeafStatement>,
             MandatoryMixin<QName, LeafStatement>, MustConstraintMixin<QName, LeafStatement> {
-    private final @NonNull Object substatements;
-    // FIXME: YANGTOOLS-1316: this seems to imply that argument.equals(declared.argument()) and we could save a field,
-    //                        except we need it in the constructors to materialize type. But if we turn it into a lazy
-    //                        field, we should be okay.
-    private final @NonNull QName argument;
-    private final @NonNull TypeDefinition<?> type;
+    private static final VarHandle TYPE;
+
+    static {
+        try {
+            TYPE = MethodHandles.lookup().findVarHandle(AbstractLeafEffectiveStatement.class, "type",
+                TypeDefinition.class);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
 
+    private final @NonNull Object substatements;
     private final int flags;
 
-    AbstractLeafEffectiveStatement(final LeafStatement declared, final QName argument, final int flags,
+    @SuppressWarnings("unused")
+    private volatile TypeDefinition<?> type;
+
+    AbstractLeafEffectiveStatement(final LeafStatement declared, final int flags,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
         super(declared);
-        this.argument = requireNonNull(argument);
-        this.substatements = maskList(substatements);
         this.flags = flags;
-        type = buildType();
+        this.substatements = maskList(substatements);
     }
 
-    AbstractLeafEffectiveStatement(final AbstractLeafEffectiveStatement original, final QName argument,
-            final int flags) {
+    AbstractLeafEffectiveStatement(final AbstractLeafEffectiveStatement original, final int flags) {
         super(original);
-        this.argument = requireNonNull(argument);
-        substatements = original.substatements;
         this.flags = flags;
-        type = buildType();
+        substatements = original.substatements;
     }
 
     @Override
@@ -72,25 +74,20 @@ public abstract class AbstractLeafEffectiveStatement
     }
 
     @Override
-    public final QName argument() {
-        return argument;
+    public final LeafEffectiveStatement asEffectiveStatement() {
+        return this;
     }
 
     @Override
     public final TypeDefinition<?> getType() {
-        return type;
+        final var local = (TypeDefinition<?>) TYPE.getAcquire(this);
+        return local != null ? local : loadType();
     }
 
-    @Override
-    public final LeafEffectiveStatement asEffectiveStatement() {
-        return this;
-    }
-
-    private TypeDefinition<?> buildType() {
-        final TypeEffectiveStatement<?> typeStmt = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).get();
-        final ConcreteTypeBuilder<?> builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(),
-            getQName());
-        for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
+    private TypeDefinition<?> loadType() {
+        final var typeStmt = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).orElseThrow();
+        final var builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(), getQName());
+        for (var stmt : effectiveSubstatements()) {
             if (stmt instanceof DefaultEffectiveStatement) {
                 builder.setDefaultValue(((DefaultEffectiveStatement)stmt).argument());
             } else if (stmt instanceof DescriptionEffectiveStatement) {
@@ -103,6 +100,9 @@ public abstract class AbstractLeafEffectiveStatement
                 builder.setUnits(((UnitsEffectiveStatement)stmt).argument());
             }
         }
-        return builder.build();
+
+        final var ret = builder.build();
+        final var witness = (TypeDefinition<?>) TYPE.compareAndExchangeRelease(this, null, ret);
+        return witness != null ? witness : ret;
     }
 }
index b22828e9b4667564b6c35e873f356bf17ae412c3..a548a04d17c4c8e4dca526ee227d00cb0f8cd9ec 100644 (file)
@@ -13,8 +13,13 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
 
 public final class EmptyLeafEffectiveStatement extends AbstractLeafEffectiveStatement {
-    public EmptyLeafEffectiveStatement(final LeafStatement declared, final QName argument, final int flags,
+    public EmptyLeafEffectiveStatement(final LeafStatement declared, final int flags,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        super(declared, argument, flags, substatements);
+        super(declared, flags, substatements);
+    }
+
+    @Override
+    public QName argument() {
+        return getDeclared().argument();
     }
 }
index 1deaeb2d0cf4ff2b397515c483ff6b6b6b748fc9..6dd9be560cce376017e6ebaba22ebd51f4aae809 100644 (file)
@@ -7,19 +7,31 @@
  */
 package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
 
 public final class RegularLeafEffectiveStatement extends AbstractLeafEffectiveStatement {
+    private final @NonNull QName argument;
+
     public RegularLeafEffectiveStatement(final LeafStatement declared, final QName argument, final int flags,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        super(declared, argument, flags, substatements);
+        super(declared, flags, substatements);
+        this.argument = requireNonNull(argument);
     }
 
     public RegularLeafEffectiveStatement(final AbstractLeafEffectiveStatement originalEffective, final QName argument,
             final int flags) {
-        super(originalEffective, argument, flags);
+        super(originalEffective, flags);
+        this.argument = requireNonNull(argument);
+    }
+
+    @Override
+    public QName argument() {
+        return argument;
     }
 }