Refactor KeyEffectiveStatementImpl 81/86881/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 9 Jan 2020 17:04:07 +0000 (18:04 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 14 Jan 2020 15:23:05 +0000 (16:23 +0100)
KeyEffectiveStatementImpl costs 32 bytes each instance in common
Linux deployment. This turns out to be unnecessary, as be can easily
drop the size to 16/24 bytes, based on whether the key is referenced
in the same module as it is defined.

The method we do this by is to provide 4 distinct implementations,
based on 2x2 matrix of locality w.r.t declared statement (same module
means we can can reuse declared argument) and number of substatements
-- "key" with a substatement is exceedingly unlikely, hence we can
usually not store substatements.

JIRA: YANGTOOLS-1065
Change-Id: Id1235131a8568236870521cb988e730a233ea96c
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 11d4ce226da8231118f5480ef5884b8e079ff437)

yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/AbstractKeyEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/EmptyForeignKeyEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/EmptyLocalKeyEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/KeyEffectiveStatementImpl.java [deleted file]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/KeyStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/RegularForeignKeyEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/RegularLocalKeyEffectiveStatement.java [new file with mode: 0644]

diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/AbstractKeyEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/AbstractKeyEffectiveStatement.java
new file mode 100644 (file)
index 0000000..5b29258
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.key;
+
+import static com.google.common.base.Verify.verify;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement;
+
+abstract class AbstractKeyEffectiveStatement
+        extends AbstractDeclaredEffectiveStatement.Default<Collection<SchemaNodeIdentifier>, KeyStatement>
+        implements KeyEffectiveStatement {
+    abstract static class Foreign extends AbstractKeyEffectiveStatement {
+        // Polymorphic, with single value or a collection
+        private final Object argument;
+
+        Foreign(final KeyStatement declared, final Collection<SchemaNodeIdentifier> argument) {
+            super(declared);
+            this.argument = argument.size() == 1 ? argument.iterator().next() : argument;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public final Collection<SchemaNodeIdentifier> argument() {
+            if (argument instanceof Collection) {
+                return (Collection<SchemaNodeIdentifier>) argument;
+            }
+            verify(argument instanceof SchemaNodeIdentifier, "Unexpected argument %s", argument);
+            return ImmutableSet.of((SchemaNodeIdentifier) argument);
+        }
+    }
+
+    abstract static class Local extends AbstractKeyEffectiveStatement {
+        Local(final KeyStatement declared) {
+            super(declared);
+        }
+
+        @Override
+        public final Collection<SchemaNodeIdentifier> argument() {
+            return getDeclared().argument();
+        }
+    }
+
+    AbstractKeyEffectiveStatement(final KeyStatement declared) {
+        super(declared);
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/EmptyForeignKeyEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/EmptyForeignKeyEffectiveStatement.java
new file mode 100644 (file)
index 0000000..b9547c5
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.key;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+
+final class EmptyForeignKeyEffectiveStatement extends AbstractKeyEffectiveStatement.Foreign {
+    EmptyForeignKeyEffectiveStatement(final KeyStatement declared, final Collection<SchemaNodeIdentifier> argument) {
+        super(declared, argument);
+    }
+
+    @Override
+    public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+        return ImmutableList.of();
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/EmptyLocalKeyEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/EmptyLocalKeyEffectiveStatement.java
new file mode 100644 (file)
index 0000000..1eb2666
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.key;
+
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+
+final class EmptyLocalKeyEffectiveStatement extends AbstractKeyEffectiveStatement.Local {
+    EmptyLocalKeyEffectiveStatement(final KeyStatement declared) {
+        super(declared);
+    }
+
+    @Override
+    public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+        return ImmutableList.of();
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/KeyEffectiveStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/KeyEffectiveStatementImpl.java
deleted file mode 100644 (file)
index a66b789..0000000
+++ /dev/null
@@ -1,23 +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.key;
-
-import java.util.Collection;
-import org.opendaylight.yangtools.yang.model.api.stmt.KeyEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.DeclaredEffectiveStatementBase;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-
-final class KeyEffectiveStatementImpl
-        extends DeclaredEffectiveStatementBase<Collection<SchemaNodeIdentifier>, KeyStatement>
-        implements KeyEffectiveStatement {
-    KeyEffectiveStatementImpl(final StmtContext<Collection<SchemaNodeIdentifier>, KeyStatement, ?> ctx) {
-        super(ctx);
-    }
-}
index 9b5f6f7c00a6eb658d488dd19f34cfafcd05ec46..1d94bd07f251b047f2f924e493c8c1a6ba7550d3 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.key;
 
 import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
 import java.util.Collection;
@@ -15,9 +16,10 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 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.KeyEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.QNameCacheNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
@@ -25,8 +27,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 public final class KeyStatementSupport
-        extends AbstractStatementSupport<Collection<SchemaNodeIdentifier>, KeyStatement,
-                EffectiveStatement<Collection<SchemaNodeIdentifier>, KeyStatement>> {
+        extends BaseStatementSupport<Collection<SchemaNodeIdentifier>, KeyStatement, KeyEffectiveStatement> {
     private static final Splitter LIST_KEY_SPLITTER = Splitter.on(' ').omitEmptyStrings().trimResults();
     private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(
         YangStmtMapping.KEY)
@@ -59,8 +60,7 @@ public final class KeyStatementSupport
 
     @Override
     public Collection<SchemaNodeIdentifier> adaptArgumentValue(
-            final StmtContext<Collection<SchemaNodeIdentifier>, KeyStatement,
-                EffectiveStatement<Collection<SchemaNodeIdentifier>, KeyStatement>> ctx,
+            final StmtContext<Collection<SchemaNodeIdentifier>, KeyStatement, KeyEffectiveStatement> ctx,
             final QNameModule targetModule) {
         final Builder<SchemaNodeIdentifier> builder = ImmutableSet.builder();
         boolean replaced = false;
@@ -86,14 +86,25 @@ public final class KeyStatementSupport
     }
 
     @Override
-    public EffectiveStatement<Collection<SchemaNodeIdentifier>, KeyStatement> createEffective(
-            final StmtContext<Collection<SchemaNodeIdentifier>, KeyStatement,
-                    EffectiveStatement<Collection<SchemaNodeIdentifier>, KeyStatement>> ctx) {
-        return new KeyEffectiveStatementImpl(ctx);
+    protected SubstatementValidator getSubstatementValidator() {
+        return SUBSTATEMENT_VALIDATOR;
     }
 
     @Override
-    protected SubstatementValidator getSubstatementValidator() {
-        return SUBSTATEMENT_VALIDATOR;
+    protected KeyEffectiveStatement createEffective(
+            final StmtContext<Collection<SchemaNodeIdentifier>, KeyStatement, KeyEffectiveStatement> ctx,
+            final KeyStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        final Collection<SchemaNodeIdentifier> arg = ctx.coerceStatementArgument();
+        return arg.equals(declared.argument()) ? new RegularLocalKeyEffectiveStatement(declared, substatements)
+                : new RegularForeignKeyEffectiveStatement(declared, arg, substatements);
+    }
+
+    @Override
+    protected KeyEffectiveStatement createEmptyEffective(
+            final StmtContext<Collection<SchemaNodeIdentifier>, KeyStatement, KeyEffectiveStatement> ctx,
+            final KeyStatement declared) {
+        final Collection<SchemaNodeIdentifier> arg = ctx.coerceStatementArgument();
+        return arg.equals(declared.argument()) ? new EmptyLocalKeyEffectiveStatement(declared)
+                : new EmptyForeignKeyEffectiveStatement(declared, arg);
     }
-}
\ No newline at end of file
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/RegularForeignKeyEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/RegularForeignKeyEffectiveStatement.java
new file mode 100644 (file)
index 0000000..a316244
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.key;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+
+final class RegularForeignKeyEffectiveStatement extends AbstractKeyEffectiveStatement.Foreign {
+    private final @NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements;
+
+    RegularForeignKeyEffectiveStatement(final KeyStatement declared, final Collection<SchemaNodeIdentifier> argument,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        super(declared, argument);
+        this.substatements = requireNonNull(substatements);
+    }
+
+    @Override
+    public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+        return substatements;
+    }
+}
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/RegularLocalKeyEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/key/RegularLocalKeyEffectiveStatement.java
new file mode 100644 (file)
index 0000000..ade4a2d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.key;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+
+final class RegularLocalKeyEffectiveStatement extends AbstractKeyEffectiveStatement.Local {
+    private final @NonNull ImmutableList<? extends EffectiveStatement<?, ?>> substatements;
+
+    RegularLocalKeyEffectiveStatement(final KeyStatement declared,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        super(declared);
+        this.substatements = requireNonNull(substatements);
+    }
+
+    @Override
+    public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+        return substatements;
+    }
+}