From bbdfd546e8f79773f2162717f607551bb79fcbda Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 13 Jan 2020 13:42:04 +0100 Subject: [PATCH] Refactor ContainerEffectiveStatementImpl The story here is very similar to ListEffectiveStatementImpl, with the additional simplifications that containers are pretty much same. Size reduction from this refactor ends up being typical 104 bytes to 40 bytes typical, eliminating a bunch of static collections in the process. JIRA: YANGTOOLS-1065 Change-Id: I1050c4e8f82f60274c78e810fc31896daccba389 Signed-off-by: Robert Varga --- .../stmt/EffectiveStatementMixins.java | 24 +++- .../AbstractContainerStatementSupport.java | 44 +++++-- .../ContainerEffectiveStatementImpl.java | 107 ++++++++++++------ 3 files changed, 128 insertions(+), 47 deletions(-) diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java index 1584c90d12..b87da7e799 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementMixins.java @@ -263,6 +263,18 @@ public final class EffectiveStatementMixins { } } + /** + * Bridge between {@link EffectiveStatementWithFlags} and {@code presence} statement. + * + * @param Argument type ({@link Void} if statement does not have argument.) + * @param Class representing declared version of this statement. + */ + public interface PresenceMixin> extends EffectiveStatementWithFlags { + default boolean presence() { + return (flags() & FlagsBuilder.PRESENCE) != 0; + } + } + /** * Bridge between {@link EffectiveStatementWithFlags} and {@link SchemaNode}. * @@ -320,7 +332,7 @@ public final class EffectiveStatementMixins { @NonNullByDefault final class FlagsBuilder implements Mutable { - // We still have 25 flags remaining + // We still have 24 flags remaining static final int STATUS_CURRENT = 0x0001; static final int STATUS_DEPRECATED = 0x0002; static final int STATUS_OBSOLETE = 0x0003; @@ -334,6 +346,7 @@ public final class EffectiveStatementMixins { private static final int MASK_HISTORY = 0x0030; static final int USER_ORDERED = 0x0040; + static final int PRESENCE = 0x0080; private int flags; @@ -373,6 +386,15 @@ public final class EffectiveStatementMixins { return this; } + public FlagsBuilder setPresence(final boolean presence) { + if (presence) { + flags |= PRESENCE; + } else { + flags &= ~PRESENCE; + } + return this; + } + public FlagsBuilder setStatus(final Status status) { final int bits; switch (status) { diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/AbstractContainerStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/AbstractContainerStatementSupport.java index 809158dcc7..b3081c994d 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/AbstractContainerStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/AbstractContainerStatementSupport.java @@ -7,19 +7,27 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.container; +import com.google.common.collect.ImmutableList; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement; import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace; -import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport; +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.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.StatementSourceReference; abstract class AbstractContainerStatementSupport - extends AbstractQNameStatementSupport> { - + extends BaseQNameStatementSupport { AbstractContainerStatementSupport() { super(YangStmtMapping.CONTAINER); } @@ -30,8 +38,7 @@ abstract class AbstractContainerStatementSupport } @Override - public final void onStatementAdded( - final Mutable> stmt) { + public final void onStatementAdded(final Mutable stmt) { stmt.coerceParentContext().addToNs(ChildSchemaNodeNamespace.class, stmt.coerceStatementArgument(), stmt); } @@ -41,8 +48,27 @@ abstract class AbstractContainerStatementSupport } @Override - public final EffectiveStatement createEffective( - final StmtContext> ctx) { - return new ContainerEffectiveStatementImpl(ctx); + protected final ContainerEffectiveStatement createEffective( + final StmtContext ctx, + final ContainerStatement declared, final ImmutableList> substatements) { + + final StatementSourceReference ref = ctx.getStatementSourceReference(); + final SchemaPath path = ctx.getSchemaPath().get(); + final ContainerSchemaNode original = (ContainerSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective) + .orElse(null); + final int flags = new FlagsBuilder() + .setHistory(ctx.getCopyHistory()) + .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT)) + .setConfiguration(ctx.isConfiguration()) + .setPresence(findFirstStatement(substatements, PresenceEffectiveStatement.class) != null) + .toFlags(); + return new ContainerEffectiveStatementImpl(declared, path, flags, ctx, substatements, original); + } + + @Override + protected final ContainerEffectiveStatement createEmptyEffective( + final StmtContext ctx, + final ContainerStatement declared) { + return createEffective(ctx, declared, ImmutableList.of()); } -} \ No newline at end of file +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/ContainerEffectiveStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/ContainerEffectiveStatementImpl.java index a64b32333d..87f8e3c9bd 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/ContainerEffectiveStatementImpl.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/ContainerEffectiveStatementImpl.java @@ -7,71 +7,104 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.container; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; +import static com.google.common.base.Verify.verify; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableList; import java.util.Objects; import java.util.Optional; -import java.util.Set; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.ActionDefinition; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode; -import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.stmt.compat.ActionNodeContainerCompat; +import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultWithDataTree; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.ActionNodeContainerMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.AugmentationTargetMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DataNodeContainerMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DataSchemaNodeMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.MustConstraintMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.NotificationNodeContainerMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.PresenceMixin; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -final class ContainerEffectiveStatementImpl extends AbstractEffectiveContainerSchemaNode - implements ContainerEffectiveStatement, DerivableSchemaNode { - private final @NonNull ImmutableSet actions; - private final @NonNull ImmutableSet notifications; +final class ContainerEffectiveStatementImpl + extends DefaultWithDataTree + implements ContainerEffectiveStatement, ContainerSchemaNode, DerivableSchemaNode, + DataSchemaNodeMixin, DataNodeContainerMixin, + ActionNodeContainerMixin, + ActionNodeContainerCompat, + NotificationNodeContainerMixin, + NotificationNodeContainerCompat, + MustConstraintMixin, PresenceMixin, + AugmentationTargetMixin { + + private final int flags; + private final @NonNull Object substatements; + private final @NonNull SchemaPath path; private final @Nullable ContainerSchemaNode original; - private final boolean presence; - - ContainerEffectiveStatementImpl( - final StmtContext> ctx) { - super(ctx); - this.original = (ContainerSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective).orElse(null); - final ImmutableSet.Builder actionsBuilder = ImmutableSet.builder(); - final Builder notificationsBuilder = ImmutableSet.builder(); - for (final EffectiveStatement effectiveStatement : effectiveSubstatements()) { - if (effectiveStatement instanceof ActionDefinition) { - actionsBuilder.add((ActionDefinition) effectiveStatement); - } - - if (effectiveStatement instanceof NotificationDefinition) { - notificationsBuilder.add((NotificationDefinition) effectiveStatement); - } + + ContainerEffectiveStatementImpl(final ContainerStatement declared, final SchemaPath path, final int flags, + final StmtContext ctx, final ImmutableList> substatements, + final ContainerSchemaNode original) { + super(declared, ctx, substatements); + + EffectiveStmtUtils.checkUniqueGroupings(ctx, substatements); + EffectiveStmtUtils.checkUniqueTypedefs(ctx, substatements); + EffectiveStmtUtils.checkUniqueUses(ctx, substatements); + + this.substatements = substatements.size() == 1 ? substatements.get(0) : substatements; + this.path = requireNonNull(path); + this.original = original; + this.flags = flags; + } + + @SuppressWarnings("unchecked") + @Override + public ImmutableList> effectiveSubstatements() { + if (substatements instanceof ImmutableList) { + return (ImmutableList>) substatements; } + verify(substatements instanceof EffectiveStatement, "Unexpected substatement %s", substatements); + return ImmutableList.of((EffectiveStatement) substatements); + } - this.actions = actionsBuilder.build(); - this.notifications = notificationsBuilder.build(); - presence = findFirstEffectiveSubstatement(PresenceEffectiveStatement.class).isPresent(); + @Override + public int flags() { + return flags; } @Override - public Optional getOriginal() { - return Optional.ofNullable(original); + public QName argument() { + return getQName(); } @Override - public Set getActions() { - return actions; + public SchemaPath getPath() { + return path; } @Override - public Set getNotifications() { - return notifications; + public Optional getOriginal() { + return Optional.ofNullable(original); } @Override public boolean isPresenceContainer() { - return presence; + return presence(); + } + + @Override + public Optional findDataChildByName(final QName name) { + return findDataSchemaNode(name); } @Override -- 2.36.6