Refactor identity statement implementations 87/87487/2
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 31 Jan 2020 14:52:15 +0000 (15:52 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 6 Feb 2020 12:34:05 +0000 (13:34 +0100)
Minimize memory footprint of identity statements, with minimal
refactor of the underlying logic.

JIRA: YANGTOOLS-1065
Change-Id: Ie3037f15164dbdf42845792adbf6d4ce33e03d94
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/AbstractIdentityEffectiveStatement.java [moved from yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/IdentityEffectiveStatementImpl.java with 70% similarity]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/AbstractIdentityStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/EmptyIdentityEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/EmptyIdentityStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/IdentityStatementImpl.java [deleted file]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/RegularIdentityEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/RegularIdentityStatement.java [new file with mode: 0644]

index f0e94be085f663ddff61636b4366c0c5028f7a0a..14868327f7ad9f22527f3f181a03d6ab38f401ad 100644 (file)
@@ -8,8 +8,13 @@
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
 import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 @Beta
 public interface IdentityEffectiveStatement extends NamespacedEffectiveStatement<IdentityStatement> {
-
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.IDENTITY;
+    }
 }
index 0ebbe18e4fe09ff33d0045fdd36f0d85b256b91a..7a2ff3c1c23d46b8f13d7caac04773133bad8733 100644 (file)
@@ -12,9 +12,16 @@ import static com.google.common.base.Verify.verifyNotNull;
 import java.util.Collection;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 public interface IdentityStatement extends DocumentedDeclaredStatement.WithStatus<QName>,
         IfFeatureAwareDeclaredStatement<QName> {
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.IDENTITY;
+    }
+
     default @NonNull QName getName() {
         // FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
         return verifyNotNull(argument());
@@ -19,21 +19,28 @@ import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveSchemaNode;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultArgument;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.SchemaNodeMixin;
 import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedIdentitiesNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-final class IdentityEffectiveStatementImpl extends AbstractEffectiveSchemaNode<IdentityStatement>
-        implements IdentityEffectiveStatement, IdentitySchemaNode, MutableStatement {
+abstract class AbstractIdentityEffectiveStatement extends DefaultArgument<QName, IdentityStatement>
+        implements IdentityEffectiveStatement, IdentitySchemaNode, MutableStatement,
+                   SchemaNodeMixin<QName, IdentityStatement> {
+    private final @NonNull SchemaPath path;
     private final ImmutableSet<IdentitySchemaNode> derivedIdentities;
+
     private @NonNull Set<IdentitySchemaNode> baseIdentities;
     private boolean sealed;
 
-    IdentityEffectiveStatementImpl(final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx) {
-        super(ctx);
+    AbstractIdentityEffectiveStatement(final IdentityStatement declared,
+            final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx) {
+        super(declared);
+        this.path = ctx.getSchemaPath().get();
 
         this.baseIdentities = new HashSet<>();
         ((StmtContext.Mutable<?, ?, ?>) ctx).addMutableStmtToSeal(this);
@@ -47,32 +54,37 @@ final class IdentityEffectiveStatementImpl extends AbstractEffectiveSchemaNode<I
             return;
         }
         for (final StmtContext<?, ?, ?> derivedIdentityCtx : derivedIdentitiesCtxList) {
-            final IdentityEffectiveStatementImpl derivedIdentity = (IdentityEffectiveStatementImpl) derivedIdentityCtx
-                    .buildEffective();
+            final AbstractIdentityEffectiveStatement derivedIdentity =
+                    (AbstractIdentityEffectiveStatement) derivedIdentityCtx.buildEffective();
             derivedIdentity.addBaseIdentity(this);
             derivedIdentitiesInit.add(derivedIdentity);
         }
         this.derivedIdentities = ImmutableSet.copyOf(derivedIdentitiesInit);
     }
 
-    private void addBaseIdentity(final IdentityEffectiveStatementImpl baseIdentity) {
+    private void addBaseIdentity(final AbstractIdentityEffectiveStatement baseIdentity) {
         checkState(!sealed, "Attempt to modify sealed identity effective statement %s", getQName());
         this.baseIdentities.add(baseIdentity);
     }
 
     @Override
-    public Set<IdentitySchemaNode> getBaseIdentities() {
+    public final SchemaPath getPath() {
+        return path;
+    }
+
+    @Override
+    public final Set<IdentitySchemaNode> getBaseIdentities() {
         checkState(sealed, "Attempt to get base identities from unsealed identity effective statement %s", getQName());
         return baseIdentities;
     }
 
     @Override
-    public Set<IdentitySchemaNode> getDerivedIdentities() {
+    public final Set<IdentitySchemaNode> getDerivedIdentities() {
         return Collections.unmodifiableSet(derivedIdentities);
     }
 
     @Override
-    public int hashCode() {
+    public final int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result + Objects.hashCode(getQName());
@@ -81,27 +93,24 @@ final class IdentityEffectiveStatementImpl extends AbstractEffectiveSchemaNode<I
     }
 
     @Override
-    public boolean equals(final Object obj) {
+    public final boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
+        if (!(obj instanceof AbstractIdentityEffectiveStatement)) {
             return false;
         }
-        final IdentityEffectiveStatementImpl other = (IdentityEffectiveStatementImpl) obj;
+        final AbstractIdentityEffectiveStatement other = (AbstractIdentityEffectiveStatement) obj;
         return Objects.equals(getQName(), other.getQName()) && Objects.equals(getPath(), other.getPath());
     }
 
     @Override
-    public String toString() {
+    public final String toString() {
         return MoreObjects.toStringHelper(this).add("qname", getQName()).add("path", getPath()).toString();
     }
 
     @Override
-    public void seal() {
+    public final void seal() {
         if (!sealed) {
             baseIdentities = ImmutableSet.copyOf(baseIdentities);
             sealed = true;
index a90edf344395d5f220b7a682286450b4ac7eaea1..7874943cabf71091bfd5640e18f6684acc5ec2d5 100644 (file)
@@ -7,19 +7,26 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.identity;
 
+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.Status;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+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.stmt.IdentityEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseQNameStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder;
 import org.opendaylight.yangtools.yang.parser.spi.IdentityNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 abstract class AbstractIdentityStatementSupport
-        extends AbstractQNameStatementSupport<IdentityStatement, IdentityEffectiveStatement> {
+        extends BaseQNameStatementSupport<IdentityStatement, IdentityEffectiveStatement> {
 
     AbstractIdentityStatementSupport() {
         super(YangStmtMapping.IDENTITY);
@@ -30,17 +37,6 @@ abstract class AbstractIdentityStatementSupport
         return StmtContextUtils.parseIdentifier(ctx, value);
     }
 
-    @Override
-    public final IdentityStatement createDeclared(final StmtContext<QName, IdentityStatement, ?> ctx) {
-        return new IdentityStatementImpl(ctx);
-    }
-
-    @Override
-    public final IdentityEffectiveStatement createEffective(
-            final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx) {
-        return new IdentityEffectiveStatementImpl(ctx);
-    }
-
     @Override
     public final void onStatementDefinitionDeclared(
             final Mutable<QName, IdentityStatement, IdentityEffectiveStatement> stmt) {
@@ -50,4 +46,32 @@ abstract class AbstractIdentityStatementSupport
                 qname);
         stmt.addToNs(IdentityNamespace.class, qname, stmt);
     }
+
+    @Override
+    protected final IdentityStatement createDeclared(final StmtContext<QName, IdentityStatement, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        return new RegularIdentityStatement(ctx.coerceStatementArgument(), substatements);
+    }
+
+    @Override
+    protected final IdentityStatement createEmptyDeclared(@NonNull final StmtContext<QName, IdentityStatement, ?> ctx) {
+        return new EmptyIdentityStatement(ctx.coerceStatementArgument());
+    }
+
+    @Override
+    protected final IdentityEffectiveStatement createEffective(
+            final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx,
+            final IdentityStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+
+        return new RegularIdentityEffectiveStatement(declared, ctx, new FlagsBuilder()
+            .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))
+            .toFlags(), substatements);
+    }
+
+    @Override
+    protected final IdentityEffectiveStatement createEmptyEffective(
+            final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx,
+            final IdentityStatement declared) {
+        return new EmptyIdentityEffectiveStatement(declared, ctx);
+    }
 }
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/EmptyIdentityEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/EmptyIdentityEffectiveStatement.java
new file mode 100644 (file)
index 0000000..9750cfc
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.identity;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+
+final class EmptyIdentityEffectiveStatement extends AbstractIdentityEffectiveStatement {
+    private static final int CURRENT_FLAGS = new FlagsBuilder().setStatus(Status.CURRENT).toFlags();
+
+    EmptyIdentityEffectiveStatement(final IdentityStatement declared,
+            final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx) {
+        super(declared, ctx);
+    }
+
+    @Override
+    public int flags() {
+        return CURRENT_FLAGS;
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/EmptyIdentityStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/EmptyIdentityStatement.java
new file mode 100644 (file)
index 0000000..0af5caa
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.identity;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument;
+
+final class EmptyIdentityStatement extends WithQNameArgument implements IdentityStatement {
+    EmptyIdentityStatement(final QName argument) {
+        super(argument);
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/IdentityStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/IdentityStatementImpl.java
deleted file mode 100644 (file)
index 62a0e6b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.identity;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-
-final class IdentityStatementImpl extends AbstractDeclaredStatement<QName> implements IdentityStatement {
-    IdentityStatementImpl(final StmtContext<QName, IdentityStatement, ?> context) {
-        super(context);
-    }
-}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/RegularIdentityEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/RegularIdentityEffectiveStatement.java
new file mode 100644 (file)
index 0000000..8bd8ac2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.identity;
+
+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.IdentityEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+
+final class RegularIdentityEffectiveStatement extends AbstractIdentityEffectiveStatement {
+    private final @NonNull Object substatements;
+    private final int flags;
+
+    RegularIdentityEffectiveStatement(final IdentityStatement declared,
+            final StmtContext<QName, IdentityStatement, IdentityEffectiveStatement> ctx, final int flags,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        super(declared, ctx);
+        this.flags = flags;
+        this.substatements = maskList(substatements);
+    }
+
+    @Override
+    public int flags() {
+        return flags;
+    }
+
+    @Override
+    public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+        return unmaskList(substatements);
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/RegularIdentityStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/identity/RegularIdentityStatement.java
new file mode 100644 (file)
index 0000000..c030767
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.identity;
+
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
+
+final class RegularIdentityStatement extends WithSubstatements implements IdentityStatement {
+    RegularIdentityStatement(final QName argument, final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(argument, substatements);
+    }
+}