BUG-6522: create a specialized CopyHistory object 83/47383/2
authorRobert Varga <rovarga@cisco.com>
Fri, 21 Oct 2016 13:45:43 +0000 (15:45 +0200)
committerRobert Varga <nite@hq.sk>
Sat, 22 Oct 2016 16:15:02 +0000 (16:15 +0000)
Copy histories have a limited number of operations, hence
mutating implementation can express the set of required operations
more efficiently. Also adds some tests to make sure the class
works correctly.

Change-Id: I0b2fd9fffa8a4bc754a9eff3808648f8f5726243
Signed-off-by: Robert Varga <rovarga@cisco.com>
15 files changed:
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSimpleDataNodeContainer.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/GroupingEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UsesEffectiveStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java [new file with mode: 0644]

diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistory.java
new file mode 100644 (file)
index 0000000..eb1e267
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016 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.spi.meta;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Verify;
+import org.opendaylight.yangtools.concepts.Immutable;
+
+@Beta
+public final class CopyHistory implements Immutable {
+    private static final CopyType[] VALUES = CopyType.values();
+
+    private static final CopyHistory[][] CACHE = new CopyHistory[VALUES.length][];
+    static {
+        /*
+         * Cache size is dependent on number of items in CopyType, it costs N * 2^N objects.
+         * For 4 types that boils down to 4 * 16 = 64 objects.
+         * For 5 types that boils down to 5 * 32 = 160 objects.
+         * For 6 types that boils down to 6 * 64 = 384 objects.
+         *
+         * If we ever hit 6 types, the caching strategy needs to be revisited.
+         */
+        Verify.verify(VALUES.length < 6);
+    }
+
+    private static final CopyHistory ORIGINAL = cacheObject(CopyType.ORIGINAL, CopyType.ORIGINAL.bit());
+
+    private final short operations;
+    private final short lastOperation;
+
+    private CopyHistory(final int operations, final CopyType lastOperation) {
+        this.operations = (short) operations;
+        this.lastOperation = (short) lastOperation.ordinal();
+    }
+
+    public static CopyHistory original() {
+        return ORIGINAL;
+    }
+
+    private static CopyHistory[] cacheArray(final CopyType lastOperation) {
+        final int ordinal = lastOperation.ordinal();
+        CopyHistory[] ret = CACHE[ordinal];
+        if (ret == null) {
+            synchronized (CACHE) {
+                ret = CACHE[ordinal];
+                if (ret == null) {
+                    ret = new CopyHistory[1 << VALUES.length];
+                    CACHE[ordinal] = ret;
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    private static CopyHistory cacheObject(final CopyType lastOperation, final int operations) {
+        final CopyHistory[] array = cacheArray(lastOperation);
+        CopyHistory ret = array[operations];
+        if (ret == null) {
+            synchronized (array) {
+                ret = array[operations];
+                if (ret == null) {
+                    ret = new CopyHistory(operations, lastOperation);
+                    array[operations] = ret;
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    public boolean contains(final CopyType type) {
+        return (operations & type.bit()) != 0;
+    }
+
+    public CopyType getLastOperation() {
+        return VALUES[lastOperation];
+    }
+
+    public CopyHistory append(final CopyType typeOfCopy, final CopyHistory toAppend) {
+        final int newOperations = operations | toAppend.operations | typeOfCopy.bit();
+        if (newOperations == operations && typeOfCopy.ordinal() == lastOperation) {
+            return this;
+        }
+
+        return cacheObject(typeOfCopy, newOperations);
+    }
+
+    @Override
+    public int hashCode() {
+        return Integer.hashCode(operations | (lastOperation << Short.SIZE));
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof CopyHistory)) {
+            return false;
+        }
+        final CopyHistory other = (CopyHistory) obj;
+        return operations == other.operations && lastOperation == other.lastOperation;
+    }
+}
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyType.java
new file mode 100644 (file)
index 0000000..1686cb1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 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.spi.meta;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Verify;
+
+@Beta
+public enum CopyType {
+    ORIGINAL,
+    ADDED_BY_USES,
+    ADDED_BY_AUGMENTATION,
+    ADDED_BY_USES_AUGMENTATION;
+
+    private final int bit;
+
+    CopyType() {
+        // CopyHistory relies on the fact that the result fits into a short
+        Verify.verify(ordinal() < Short.SIZE);
+        bit = 1 << ordinal();
+    }
+
+    int bit() {
+        return bit;
+    }
+}
\ No newline at end of file
index fd44a86e0d4a06951d2a943ee2505839d0648fd0..b49363f991551e002685471d47371bd35ba53953 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.parser.spi.meta;
 
 import com.google.common.base.Optional;
 import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -88,18 +87,14 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
     void addAsEffectOfStatement(StatementContextBase<?, ?, ?> ctx);
 
     StatementContextBase<?, ?, ?> createCopy(
-            StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
+            StatementContextBase<?, ?, ?> newParent, CopyType typeOfCopy)
             throws SourceException;
 
     StatementContextBase<?, ?, ?> createCopy(QNameModule newQNameModule,
-            StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
+            StatementContextBase<?, ?, ?> newParent, CopyType typeOfCopy)
             throws SourceException;
 
-    enum TypeOfCopy {
-        ORIGINAL, ADDED_BY_USES, ADDED_BY_AUGMENTATION, ADDED_BY_USES_AUGMENTATION
-    }
-
-    List<TypeOfCopy> getCopyHistory();
+    CopyHistory getCopyHistory();
 
     enum SupportedByFeatures {
         UNDEFINED, SUPPORTED, NOT_SUPPORTED
@@ -107,9 +102,7 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
 
     SupportedByFeatures getSupportedByFeatures();
 
-    void addAllToCopyHistory(List<TypeOfCopy> typeOfCopyList);
-
-    void addToCopyHistory(TypeOfCopy typeOfCopy);
+    void appendCopyHistory(CopyType typeOfCopy, CopyHistory toAppend);
 
     StatementContextBase<?, ?, ?> getOriginalCtx();
 
index 54f93ebe8ac36b35dfd991454c771db90cb92663..36e406233a3c166057c562cb83797a356037d7b9 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Regist
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IncludedModuleContext;
 
 /**
@@ -41,7 +42,7 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
     }
 
     RootStatementContext(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
-        final TypeOfCopy typeOfCopy) {
+        final CopyType typeOfCopy) {
         super(original);
 
         sourceContext = original.sourceContext;
@@ -61,7 +62,7 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException
      */
     private void copyDeclaredStmts(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
-            final TypeOfCopy typeOfCopy) {
+            final CopyType typeOfCopy) {
         final Collection<StatementContextBase<?, ?, ?>> originalDeclaredSubstatements = original.declaredSubstatements();
         for (final StatementContextBase<?, ?, ?> stmtContext : originalDeclaredSubstatements) {
             if (!StmtContextUtils.areFeaturesSupported(stmtContext)) {
@@ -79,7 +80,7 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException
      */
     private void copyEffectiveStmts(final RootStatementContext<A, D, E> original, final QNameModule newQNameModule,
-            final TypeOfCopy typeOfCopy) {
+            final CopyType typeOfCopy) {
         final Collection<? extends StmtContext<?, ?, ?>> originalEffectiveSubstatements = original.effectiveSubstatements();
         for (final StmtContext<?, ?, ?> stmtContext : originalEffectiveSubstatements) {
             this.addEffectiveSubstatement(stmtContext.createCopy(newQNameModule, this, typeOfCopy));
@@ -132,28 +133,27 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
     }
 
     /**
-     * @return copy of this considering {@link TypeOfCopy} (augment, uses)
+     * @return copy of this considering {@link CopyType} (augment, uses)
      *
      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
      */
     @Override
     public StatementContextBase<?, ?, ?> createCopy(final StatementContextBase<?, ?, ?> newParent,
-            final TypeOfCopy typeOfCopy) {
+            final CopyType typeOfCopy) {
         return createCopy(null, newParent, typeOfCopy);
     }
 
     /**
-     * @return copy of this considering {@link TypeOfCopy} (augment, uses)
+     * @return copy of this considering {@link CopyType} (augment, uses)
      *
      * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException instance of SourceException
      */
     @Override
     public StatementContextBase<A, D, E> createCopy(final QNameModule newQNameModule,
-            final StatementContextBase<?, ?, ?> newParent, final TypeOfCopy typeOfCopy) {
+            final StatementContextBase<?, ?, ?> newParent, final CopyType typeOfCopy) {
         final RootStatementContext<A, D, E> copy = new RootStatementContext<>(this, newQNameModule, typeOfCopy);
 
-        copy.addAllToCopyHistory(this.getCopyHistory());
-        copy.addToCopyHistory(typeOfCopy);
+        copy.appendCopyHistory(typeOfCopy, this.getCopyHistory());
 
         if (this.getOriginalCtx() != null) {
             copy.setOriginalCtx(this.getOriginalCtx());
index 8d92f34f9b5226185f00ab0771d105c76009d0f6..bb45a4a78ca968922f65b5602e85080de9a19fb4 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
 import java.util.ArrayList;
@@ -19,7 +18,6 @@ import java.util.EnumMap;
 import java.util.EventListener;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.concepts.Identifiable;
@@ -29,6 +27,8 @@ 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.parser.spi.meta.CopyHistory;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
@@ -71,8 +71,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         boolean isFinished();
     }
 
-    private final static List<TypeOfCopy> ORIGINAL_COPY = ImmutableList.of(TypeOfCopy.ORIGINAL);
-
     private final StatementDefinitionContext<A, D, E> definition;
     private final StatementIdentifier identifier;
     private final StatementSourceReference statementDeclSource;
@@ -90,7 +88,7 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     private final Collection<StatementContextBase<?, ?, ?>> effectOfStatement = new ArrayList<>(1);
 
     private SupportedByFeatures supportedByFeatures = SupportedByFeatures.UNDEFINED;
-    private List<TypeOfCopy> copyHistory = ORIGINAL_COPY;
+    private CopyHistory copyHistory = CopyHistory.original();
     private boolean isSupportedToBuildEffective = true;
     private ModelProcessingPhase completedPhase = null;
     private StatementContextBase<?, ?, ?> originalCtx;
@@ -144,28 +142,13 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     @Override
-    public List<TypeOfCopy> getCopyHistory() {
+    public CopyHistory getCopyHistory() {
         return copyHistory;
     }
 
-    private void growCopyHistory(final int growBy) {
-        if (copyHistory == ORIGINAL_COPY) {
-            final List<TypeOfCopy> newCopyHistory = new ArrayList<>(growBy + 1);
-            newCopyHistory.add(TypeOfCopy.ORIGINAL);
-            copyHistory = newCopyHistory;
-        }
-    }
-
-    @Override
-    public void addToCopyHistory(final TypeOfCopy typeOfCopy) {
-        growCopyHistory(1);
-        this.copyHistory.add(typeOfCopy);
-    }
-
     @Override
-    public void addAllToCopyHistory(final List<TypeOfCopy> typeOfCopyList) {
-        growCopyHistory(typeOfCopyList.size());
-        this.copyHistory.addAll(typeOfCopyList);
+    public void appendCopyHistory(final CopyType typeOfCopy, final CopyHistory toAppend) {
+        copyHistory = copyHistory.append(typeOfCopy, toAppend);
     }
 
     @Override
index 5536dfe7c59fd16123001bfb4e8de484b1d1d161..6d369e6b6f50840da796725889ad195ba5ed8b6b 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
@@ -50,7 +51,7 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
 
     @SuppressWarnings("unchecked")
     SubstatementContext(final SubstatementContext<A, D, E> original, final QNameModule newQNameModule,
-            final StatementContextBase<?, ?, ?> newParent, final TypeOfCopy typeOfCopy) {
+            final StatementContextBase<?, ?, ?> newParent, final CopyType typeOfCopy) {
         super(original);
         this.parent = newParent;
 
@@ -71,7 +72,7 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
     }
 
     private void copyDeclaredStmts(final SubstatementContext<A, D, E> original, final QNameModule newQNameModule,
-            final TypeOfCopy typeOfCopy) {
+            final CopyType typeOfCopy) {
         final Collection<? extends StatementContextBase<?, ?, ?>> originalDeclaredSubstatements = original
                 .declaredSubstatements();
         for (final StatementContextBase<?, ?, ?> stmtContext : originalDeclaredSubstatements) {
@@ -88,7 +89,7 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
     }
 
     private void copyEffectiveStmts(final SubstatementContext<A, D, E> original, final QNameModule newQNameModule,
-            final TypeOfCopy typeOfCopy) {
+            final CopyType typeOfCopy) {
         final Collection<? extends StatementContextBase<?, ?, ?>> originalEffectiveSubstatements = original
                 .effectiveSubstatements();
         for (final StatementContextBase<?, ?, ?> stmtContext : originalEffectiveSubstatements) {
@@ -128,17 +129,16 @@ final class SubstatementContext<A, D extends DeclaredStatement<A>, E extends Eff
 
     @Override
     public StatementContextBase<?, ?, ?> createCopy(final StatementContextBase<?, ?, ?> newParent,
-            final TypeOfCopy typeOfCopy) {
+            final CopyType typeOfCopy) {
         return createCopy(null, newParent, typeOfCopy);
     }
 
     @Override
     public StatementContextBase<A, D, E> createCopy(final QNameModule newQNameModule,
-            final StatementContextBase<?, ?, ?> newParent, final TypeOfCopy typeOfCopy) {
+            final StatementContextBase<?, ?, ?> newParent, final CopyType typeOfCopy) {
         final SubstatementContext<A, D, E> copy = new SubstatementContext<>(this, newQNameModule, newParent, typeOfCopy);
 
-        copy.addAllToCopyHistory(this.getCopyHistory());
-        copy.addToCopyHistory(typeOfCopy);
+        copy.appendCopyHistory(typeOfCopy, this.getCopyHistory());
 
         if (this.getOriginalCtx() != null) {
             copy.setOriginalCtx(this.getOriginalCtx());
index 2ae751d4aad45127afb44068ba2f78eb20fa1170..09e78b4b420405930664af7df6ba92c20eaf8ec6 100644 (file)
@@ -22,8 +22,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext;
@@ -44,9 +44,9 @@ public final class AugmentUtils {
     private static void copyDeclaredStmts(final StatementContextBase<?, ?, ?> sourceCtx,
             final StatementContextBase<?, ?, ?> targetCtx) {
 
-        final TypeOfCopy typeOfCopy = sourceCtx.getParentContext().getPublicDefinition()
-                .getDeclaredRepresentationClass().equals(UsesStatement.class) ? TypeOfCopy.ADDED_BY_USES_AUGMENTATION
-                : TypeOfCopy.ADDED_BY_AUGMENTATION;
+        final CopyType typeOfCopy = sourceCtx.getParentContext().getPublicDefinition()
+                .getDeclaredRepresentationClass().equals(UsesStatement.class) ? CopyType.ADDED_BY_USES_AUGMENTATION
+                : CopyType.ADDED_BY_AUGMENTATION;
 
         for (final StatementContextBase<?, ?, ?> originalStmtCtx : sourceCtx.declaredSubstatements()) {
             if (!StmtContextUtils.areFeaturesSupported(originalStmtCtx)) {
@@ -65,9 +65,9 @@ public final class AugmentUtils {
 
     private static void copyEffectiveStmts(final StatementContextBase<?, ?, ?> sourceCtx,
             final StatementContextBase<?, ?, ?> targetCtx) {
-        final TypeOfCopy typeOfCopy = sourceCtx.getParentContext().getPublicDefinition()
-                .getDeclaredRepresentationClass().equals(UsesStatement.class) ? TypeOfCopy.ADDED_BY_USES_AUGMENTATION
-                : TypeOfCopy.ADDED_BY_AUGMENTATION;
+        final CopyType typeOfCopy = sourceCtx.getParentContext().getPublicDefinition()
+                .getDeclaredRepresentationClass().equals(UsesStatement.class) ? CopyType.ADDED_BY_USES_AUGMENTATION
+                : CopyType.ADDED_BY_AUGMENTATION;
 
         for (final StatementContextBase<?, ?, ?> originalStmtCtx : sourceCtx.effectiveSubstatements()) {
             if (needToCopyByAugment(originalStmtCtx)) {
@@ -82,13 +82,13 @@ public final class AugmentUtils {
     }
 
     private static void validateNodeCanBeCopiedByAugment(final StatementContextBase<?, ?, ?> sourceCtx,
-            final StatementContextBase<?, ?, ?> targetCtx, final TypeOfCopy typeOfCopy) {
+            final StatementContextBase<?, ?, ?> targetCtx, final CopyType typeOfCopy) {
 
         if (sourceCtx.getPublicDefinition().getDeclaredRepresentationClass().equals(WhenStatement.class)) {
             return;
         }
 
-        if (typeOfCopy == TypeOfCopy.ADDED_BY_AUGMENTATION && reguiredCheckOfMandatoryNodes(sourceCtx, targetCtx)) {
+        if (typeOfCopy == CopyType.ADDED_BY_AUGMENTATION && reguiredCheckOfMandatoryNodes(sourceCtx, targetCtx)) {
             final List<StatementContextBase<?, ?, ?>> sourceSubStatements = new Builder<StatementContextBase<?, ?, ?>>()
                     .addAll(sourceCtx.declaredSubstatements()).addAll(sourceCtx.effectiveSubstatements()).build();
 
index b16054ee05976a03bd0779f04527afb860d9f178..5c7954526e8ea4df4817614f9579d0e620677a30 100644 (file)
@@ -19,9 +19,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 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.StmtContext.TypeOfCopy;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@@ -68,7 +68,7 @@ public final class GroupingUtils {
             }
             if (needToCopyByUses(originalStmtCtx)) {
                 final StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx,
-                        TypeOfCopy.ADDED_BY_USES);
+                        CopyType.ADDED_BY_USES);
                 targetCtx.addEffectiveSubstatement(copy);
                 usesNode.addAsEffectOfStatement(copy);
             } else if (isReusedByUsesOnTop(originalStmtCtx)) {
@@ -85,7 +85,7 @@ public final class GroupingUtils {
         for (final StatementContextBase<?, ?, ?> originalStmtCtx : sourceGrpStmtCtx.effectiveSubstatements()) {
             if (needToCopyByUses(originalStmtCtx)) {
                 final StatementContextBase<?, ?, ?> copy = originalStmtCtx.createCopy(newQNameModule, targetCtx,
-                        TypeOfCopy.ADDED_BY_USES);
+                        CopyType.ADDED_BY_USES);
                 targetCtx.addEffectiveSubstatement(copy);
                 usesNode.addAsEffectOfStatement(copy);
             } else if (isReusedByUsesOnTop(originalStmtCtx)) {
index abd4ce7c749e533dded6d2ccc1168c8a41a92d53..30321e3b6088c92d4585e72a15e6159f8a92e809 100644 (file)
@@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -57,6 +56,7 @@ import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
 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;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
@@ -515,7 +515,7 @@ public final class Utils {
                 qNameModule = getRootModuleQName(ctx);
             }
             if (qNameModule == null
-                    && Iterables.getLast(ctx.getCopyHistory()) == StmtContext.TypeOfCopy.ADDED_BY_AUGMENTATION) {
+                    && ctx.getCopyHistory().getLastOperation() == CopyType.ADDED_BY_AUGMENTATION) {
                 ctx = ctx.getOriginalCtx();
                 qNameModule = getModuleQNameByPrefix(ctx, prefix);
             }
@@ -697,7 +697,7 @@ public final class Utils {
         return false;
     }
 
-    public static SourceIdentifier createSourceIdentifier(RootStatementContext<?, ?, ?> root) {
+    public static SourceIdentifier createSourceIdentifier(final RootStatementContext<?, ?, ?> root) {
         final QNameModule qNameModule = root.getFromNamespace(ModuleCtxToModuleQName.class, root);
         if (qNameModule != null) {
             // creates SourceIdentifier for a module
index b8863bda726c896d8ef12ed9a75dac1f6558756b..c82beb5a1eda33fc41deff6fcbd6817e16c7ec95 100644 (file)
@@ -7,13 +7,13 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import java.util.List;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 
 abstract class AbstractEffectiveDataSchemaNode<D extends DeclaredStatement<QName>> extends
         AbstractEffectiveSchemaNode<D> implements DataSchemaNode {
@@ -30,12 +30,12 @@ abstract class AbstractEffectiveDataSchemaNode<D extends DeclaredStatement<QName
         this.configuration = ctx.isConfiguration();
 
         // initCopyType
-        List<TypeOfCopy> copyTypesFromOriginal = ctx.getCopyHistory();
-        if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) {
+        final CopyHistory originalHistory = ctx.getCopyHistory();
+        if (originalHistory.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) {
             this.addedByUses = this.augmenting = true;
         } else {
-            this.augmenting = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION);
-            this.addedByUses = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES);
+            this.augmenting = originalHistory.contains(CopyType.ADDED_BY_AUGMENTATION);
+            this.addedByUses = originalHistory.contains(CopyType.ADDED_BY_USES);
         }
     }
 
index e343df40118cef522389e91872a553c6df64cc81..c6cde2adb8bbf37caf9033a57daa5e0527c11b3e 100644 (file)
@@ -23,8 +23,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 
 abstract class AbstractEffectiveSimpleDataNodeContainer<D extends DeclaredStatement<QName>> extends
         AbstractEffectiveDocumentedDataNodeContainer<QName, D> implements DataNodeContainer, AugmentationTarget,
@@ -64,12 +65,12 @@ abstract class AbstractEffectiveSimpleDataNodeContainer<D extends DeclaredStatem
         this.augmentations = ImmutableSet.copyOf(augmentationsInit);
 
         // initCopyType
-        List<TypeOfCopy> copyTypesFromOriginal = ctx.getCopyHistory();
-        if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) {
+        final CopyHistory copyTypesFromOriginal = ctx.getCopyHistory();
+        if (copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) {
             this.addedByUses = this.augmenting = true;
         } else {
-            this.augmenting = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION);
-            this.addedByUses = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES);
+            this.augmenting = copyTypesFromOriginal.contains(CopyType.ADDED_BY_AUGMENTATION);
+            this.addedByUses = copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES);
         }
     }
 
index 8a83eb9d1919bd30ca5c85c0a17549ad3d14baf3..d526f002e3e1df7f8c23c76f61dd204c2c9229a3 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 
 public class GroupingEffectiveStatementImpl extends
         AbstractEffectiveDocumentedDataNodeContainer<QName, GroupingStatement> implements GroupingDefinition {
@@ -35,13 +35,7 @@ public class GroupingEffectiveStatementImpl extends
         qname = ctx.getStatementArgument();
         path = ctx.getSchemaPath().get();
 
-        // initCopyType
-        List<TypeOfCopy> copyTypesFromOriginal = ctx.getCopyHistory();
-        if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) {
-            addedByUses = true;
-        } else {
-            addedByUses = false;
-        }
+        addedByUses = ctx.getCopyHistory().contains(CopyType.ADDED_BY_USES);
 
         final Builder<UnknownSchemaNode> b = ImmutableList.builder();
         for (EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
index 1fbf48fc3dc02148462dd5940538aa82fe783721..1a281b55cfe06467b14f2cb9cd7f68ab08a50792 100644 (file)
@@ -18,8 +18,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 
 public abstract class UnknownEffectiveStatementBase<A> extends AbstractEffectiveDocumentedNode<A, UnknownStatement<A>>
         implements UnknownSchemaNode {
@@ -47,12 +48,12 @@ public abstract class UnknownEffectiveStatementBase<A> extends AbstractEffective
         }
 
         // initCopyType
-        List<TypeOfCopy> copyTypesFromOriginal = ctx.getCopyHistory();
-        if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES_AUGMENTATION)) {
+        final CopyHistory copyTypesFromOriginal = ctx.getCopyHistory();
+        if (copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) {
             this.addedByUses = this.addedByAugmentation = true;
         } else {
-            this.addedByAugmentation = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_AUGMENTATION);
-            this.addedByUses = copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES);
+            this.addedByAugmentation = copyTypesFromOriginal.contains(CopyType.ADDED_BY_AUGMENTATION);
+            this.addedByUses = copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES);
         }
 
         nodeParameter = (ctx.rawStatementArgument() == null) ? "" : ctx.rawStatementArgument();
index a861f354dd5d37abec80825b80232e6cc57ec763..cb212de724f0c1766b6887ef58d8f4aa84567842 100644 (file)
@@ -32,7 +32,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
+import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
 
 public final class UsesEffectiveStatementImpl extends AbstractEffectiveDocumentedNode<QName, UsesStatement> implements UsesNode {
     private final SchemaPath groupingPath;
@@ -52,12 +52,7 @@ public final class UsesEffectiveStatementImpl extends AbstractEffectiveDocumente
         this.groupingPath = grpCtx.getSchemaPath().get();
 
         // initCopyType
-        final List<TypeOfCopy> copyTypesFromOriginal = ctx.getCopyHistory();
-        if (copyTypesFromOriginal.contains(TypeOfCopy.ADDED_BY_USES)) {
-            addedByUses = true;
-        } else {
-            addedByUses = false;
-        }
+        addedByUses = ctx.getCopyHistory().contains(CopyType.ADDED_BY_USES);
 
         // initSubstatementCollections
         final Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements = effectiveSubstatements();
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/spi/meta/CopyHistoryTest.java
new file mode 100644 (file)
index 0000000..6a5c112
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 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.spi.meta;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class CopyHistoryTest {
+
+    @Test
+    public void testSingleton() {
+        final CopyHistory original = CopyHistory.original();
+
+        assertEquals(CopyType.ORIGINAL, original.getLastOperation());
+        assertTrue(original.contains(CopyType.ORIGINAL));
+        assertFalse(original.contains(CopyType.ADDED_BY_USES));
+        assertFalse(original.contains(CopyType.ADDED_BY_AUGMENTATION));
+        assertFalse(original.contains(CopyType.ADDED_BY_USES_AUGMENTATION));
+
+        assertSame(original, CopyHistory.original());
+    }
+
+    @Test
+    public void testAppend() {
+        final CopyHistory original = CopyHistory.original();
+        assertSame(original, original.append(CopyType.ORIGINAL, original));
+
+        final CopyHistory originalUA = original.append(CopyType.ADDED_BY_USES_AUGMENTATION, original);
+        assertEquals(CopyType.ADDED_BY_USES_AUGMENTATION, originalUA.getLastOperation());
+        assertTrue(originalUA.contains(CopyType.ORIGINAL));
+        assertFalse(originalUA.contains(CopyType.ADDED_BY_USES));
+        assertFalse(originalUA.contains(CopyType.ADDED_BY_AUGMENTATION));
+        assertTrue(originalUA.contains(CopyType.ADDED_BY_USES_AUGMENTATION));
+
+        assertSame(originalUA, original.append(CopyType.ADDED_BY_USES_AUGMENTATION, original));
+        assertSame(originalUA, originalUA.append(CopyType.ADDED_BY_USES_AUGMENTATION, original));
+
+        final CopyHistory originalU = original.append(CopyType.ADDED_BY_USES, original);
+        assertEquals(CopyType.ADDED_BY_USES, originalU.getLastOperation());
+        assertTrue(originalU.contains(CopyType.ORIGINAL));
+        assertTrue(originalU.contains(CopyType.ADDED_BY_USES));
+        assertFalse(originalU.contains(CopyType.ADDED_BY_AUGMENTATION));
+        assertFalse(originalU.contains(CopyType.ADDED_BY_USES_AUGMENTATION));
+
+        final CopyHistory uaU = originalUA.append(CopyType.ADDED_BY_USES, original);
+        assertEquals(CopyType.ADDED_BY_USES, uaU.getLastOperation());
+        assertTrue(uaU.contains(CopyType.ORIGINAL));
+        assertTrue(uaU.contains(CopyType.ADDED_BY_USES));
+        assertFalse(uaU.contains(CopyType.ADDED_BY_AUGMENTATION));
+        assertTrue(uaU.contains(CopyType.ADDED_BY_USES_AUGMENTATION));
+
+        assertSame(uaU, originalUA.append(CopyType.ADDED_BY_USES, original));
+
+        final CopyHistory res = originalUA.append(CopyType.ADDED_BY_AUGMENTATION, originalU);
+        assertEquals(CopyType.ADDED_BY_AUGMENTATION, res.getLastOperation());
+        assertTrue(res.contains(CopyType.ORIGINAL));
+        assertTrue(res.contains(CopyType.ADDED_BY_USES));
+        assertTrue(res.contains(CopyType.ADDED_BY_AUGMENTATION));
+        assertTrue(res.contains(CopyType.ADDED_BY_USES_AUGMENTATION));
+    }
+
+}