Share MandatoryStatement instances 65/29465/3
authorRobert Varga <rovarga@cisco.com>
Mon, 9 Nov 2015 18:46:03 +0000 (19:46 +0100)
committerRobert Varga <rovarga@cisco.com>
Tue, 10 Nov 2015 00:21:54 +0000 (01:21 +0100)
Heap dump analysis shows we are wasting memory on MandatoryStatementImpl
instances which are empty. Fix this by creating two dedicated classes
which handle the 'mandatory true' and 'mandatory false' cases.

Same goes for MandatoryEffectiveStatementImpl, for which we provide an
alternative implementation, requiring an MandatoryEffectiveStatement
interface, so that it can be looked up.

Change-Id: If126c3b8d81ad4a870088285ff8956724b199134
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EmptyMandatoryEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EmptyMandatoryStatement.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/MandatoryStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MandatoryEffectiveStatement.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MandatoryEffectiveStatementImpl.java

diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EmptyMandatoryEffectiveStatement.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EmptyMandatoryEffectiveStatement.java
new file mode 100644 (file)
index 0000000..7d3fb81
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * 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.stmt.rfc6020;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.MandatoryEffectiveStatement;
+
+abstract class EmptyMandatoryEffectiveStatement implements MandatoryEffectiveStatement {
+    static final EmptyMandatoryEffectiveStatement FALSE = new EmptyMandatoryEffectiveStatement() {
+        @Override
+        public MandatoryStatement getDeclared() {
+            return EmptyMandatoryStatement.FALSE;
+        }
+    };
+
+    static final EmptyMandatoryEffectiveStatement TRUE = new EmptyMandatoryEffectiveStatement() {
+        @Override
+        public MandatoryStatement getDeclared() {
+            return EmptyMandatoryStatement.TRUE;
+        }
+    };
+
+    private EmptyMandatoryEffectiveStatement() {
+        // Hidden
+    }
+
+    @Override
+    public final StatementDefinition statementDefinition() {
+        return getDeclared().statementDefinition();
+    }
+
+    @Override
+    public final Boolean argument() {
+        return getDeclared().argument();
+    }
+
+    @Override
+    public final StatementSource getStatementSource() {
+        return getDeclared().getStatementSource();
+    }
+
+    @Override
+    public final <K, V, N extends IdentifierNamespace<K, V>> V get(final Class<N> namespace, final K identifier) {
+        throw new UnsupportedOperationException("Not implemented yet.");
+    }
+
+    @Override
+    public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
+        throw new UnsupportedOperationException("Not implemented yet.");
+    }
+
+    @Override
+    public final Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+        return ImmutableList.of();
+    }
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EmptyMandatoryStatement.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/EmptyMandatoryStatement.java
new file mode 100644 (file)
index 0000000..b83dbd8
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * 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.stmt.rfc6020;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
+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.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
+
+abstract class EmptyMandatoryStatement implements MandatoryStatement {
+    static final MandatoryStatement FALSE = new EmptyMandatoryStatement() {
+        @Override
+        public Boolean getValue() {
+            return Boolean.FALSE;
+        }
+
+        @Override
+        EffectiveStatement<Boolean, MandatoryStatement> toEffective() {
+            return EmptyMandatoryEffectiveStatement.FALSE;
+        }
+    };
+
+    static final MandatoryStatement TRUE = new EmptyMandatoryStatement() {
+        @Override
+        public Boolean getValue() {
+            return Boolean.TRUE;
+        }
+
+        @Override
+        EffectiveStatement<Boolean, MandatoryStatement> toEffective() {
+            return EmptyMandatoryEffectiveStatement.TRUE;
+        }
+    };
+
+    private EmptyMandatoryStatement() {
+        // Invisible on purpose
+    }
+
+    abstract EffectiveStatement<Boolean, MandatoryStatement> toEffective();
+
+    @Override
+    public final Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public final StatementDefinition statementDefinition() {
+        return Rfc6020Mapping.MANDATORY;
+    }
+
+    @Override
+    public final String rawArgument() {
+        return getValue().toString();
+    }
+
+    @Override
+    public final Boolean argument() {
+        return getValue();
+    }
+
+    @Override
+    public final StatementSource getStatementSource() {
+        return StatementSource.DECLARATION;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(statementDefinition(), getStatementSource(), argument(),
+            rawArgument(), declaredSubstatements(), getValue());
+    }
+
+    @Override
+    public final boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MandatoryStatement)) {
+            return false;
+        }
+
+        final MandatoryStatement other = (MandatoryStatement) obj;
+
+        return  argument().equals(other.argument()) &&
+                rawArgument().equals(other.rawArgument()) &&
+                getValue().equals(other.getValue()) &&
+                statementDefinition().equals(other.statementDefinition()) &&
+                getStatementSource().equals(other.getStatementSource()) &&
+                declaredSubstatements().equals(other.declaredSubstatements());
+    }
+}
index d2b30d071b83a5b097eae06e20b4465470cccdfc..3e8cb0bf60144a9364abfeb7506f62c4dd81af28 100644 (file)
@@ -7,49 +7,59 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.MandatoryEffectiveStatementImpl;
-
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.MandatoryEffectiveStatementImpl;
 
-public class MandatoryStatementImpl extends AbstractDeclaredStatement<Boolean> implements
-        MandatoryStatement {
+public class MandatoryStatementImpl extends AbstractDeclaredStatement<Boolean> implements MandatoryStatement {
 
-    protected MandatoryStatementImpl(
-            StmtContext<Boolean, MandatoryStatement, ?> context) {
+    protected MandatoryStatementImpl(final StmtContext<Boolean, MandatoryStatement, ?> context) {
         super(context);
     }
 
-    public static class Definition extends AbstractStatementSupport<Boolean,MandatoryStatement,EffectiveStatement<Boolean,MandatoryStatement>> {
+    public static class Definition extends
+        AbstractStatementSupport<Boolean, MandatoryStatement, EffectiveStatement<Boolean, MandatoryStatement>> {
 
         public Definition() {
             super(Rfc6020Mapping.MANDATORY);
         }
 
-        @Override public Boolean parseArgumentValue(
-                StmtContext<?, ?, ?> ctx, String value) throws SourceException {
+        @Override
+        public Boolean parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
             return Boolean.valueOf(value);
         }
 
-        @Override public MandatoryStatement createDeclared(
-                StmtContext<Boolean, MandatoryStatement, ?> ctx) {
-            return new MandatoryStatementImpl(ctx);
+        @Override
+        public MandatoryStatement createDeclared(final StmtContext<Boolean, MandatoryStatement, ?> ctx) {
+            final MandatoryStatement ret = new MandatoryStatementImpl(ctx);
+            if (EmptyMandatoryStatement.FALSE.equals(ret)) {
+                return EmptyMandatoryStatement.FALSE;
+            } else if (EmptyMandatoryStatement.TRUE.equals(ret)) {
+                return EmptyMandatoryStatement.TRUE;
+            } else {
+                return ret;
+            }
         }
 
-        @Override public EffectiveStatement<Boolean, MandatoryStatement> createEffective(
-                StmtContext<Boolean, MandatoryStatement, EffectiveStatement<Boolean, MandatoryStatement>> ctx) {
-            return new MandatoryEffectiveStatementImpl(ctx);
+        @Override
+        public EffectiveStatement<Boolean, MandatoryStatement> createEffective(
+                final StmtContext<Boolean, MandatoryStatement, EffectiveStatement<Boolean, MandatoryStatement>> ctx) {
+            final EffectiveStatement<Boolean, MandatoryStatement> ret = new MandatoryEffectiveStatementImpl(ctx);
+            final MandatoryStatement declared = ret.getDeclared();
+            if (declared instanceof EmptyMandatoryStatement && ret.effectiveSubstatements().isEmpty()) {
+                return ((EmptyMandatoryStatement)declared).toEffective();
+            }
+            return ret;
         }
     }
 
-    @Nonnull @Override
-    public Boolean getValue() {
+    @Override
+    @Nonnull public Boolean getValue() {
         return argument();
     }
 }
index 8b39b4bfde63edba39e04f7beea788ddb0513d76..72e981d42916760f155e08abc3a87421c7446e69 100644 (file)
@@ -48,8 +48,7 @@ final class EffectiveConstraintDefinitionImpl implements ConstraintDefinition {
             maxElements = Integer.valueOf(maxElementsArg);
         }
 
-        final MandatoryEffectiveStatementImpl firstMandatoryStmt = parent
-                .firstEffective(MandatoryEffectiveStatementImpl.class);
+        final MandatoryEffectiveStatement firstMandatoryStmt = parent.firstEffective(MandatoryEffectiveStatement.class);
         final boolean mandatory = (firstMandatoryStmt == null) ? minElements > 0 : firstMandatoryStmt.argument();
 
         final Set<MustDefinition> mustSubstatements = ImmutableSet.copyOf(parent.allSubstatementsOfType(
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MandatoryEffectiveStatement.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/MandatoryEffectiveStatement.java
new file mode 100644 (file)
index 0000000..b443b9c
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * 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.stmt.rfc6020.effective;
+
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
+
+public interface MandatoryEffectiveStatement extends EffectiveStatement<Boolean, MandatoryStatement> {
+
+}
index b1eda0d3508c8e5c1b771ffe207e493d5eb38211..3d875479d9fe3dee79f2bb164bb42feb3f5d7e42 100644 (file)
@@ -10,8 +10,9 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-public final class MandatoryEffectiveStatementImpl extends EffectiveStatementBase<Boolean, MandatoryStatement> {
+public final class MandatoryEffectiveStatementImpl extends EffectiveStatementBase<Boolean, MandatoryStatement>
+    implements MandatoryEffectiveStatement {
     public MandatoryEffectiveStatementImpl(final StmtContext<Boolean, MandatoryStatement, ?> ctx) {
         super(ctx);
     }
-}
\ No newline at end of file
+}