CopyHistory should be an interface
[yangtools.git] / yang / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / CopyHistory.java
index 8b4e5846b532e656f0a5ab426e3d762c3df0a04d..72b77014a5aaeea1b75495902309fccc6786d672 100644 (file)
 package org.opendaylight.yangtools.yang.parser.spi.meta;
 
 import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Verify;
-import java.util.Arrays;
-import java.util.stream.Collectors;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.model.api.CopyableNode;
 
+/**
+ * Reactor's view of significant semantic history of a particular statement.
+ */
 @Beta
-public final class CopyHistory implements Immutable, CopyableNode {
-    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 static final int IS_ADDED_BY_USES_BITS =
-        CopyType.ADDED_BY_USES_AUGMENTATION.bit() | CopyType.ADDED_BY_USES.bit();
-    private static final int IS_AUGMENTING_BITS =
-        CopyType.ADDED_BY_USES_AUGMENTATION.bit() | CopyType.ADDED_BY_AUGMENTATION.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;
-    }
-
-    public static CopyHistory of(final CopyType copyType, final CopyHistory copyHistory) {
-        return ORIGINAL.append(copyType, copyHistory);
-    }
-
-    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 CopyType getLastOperation() {
-        return VALUES[lastOperation];
-    }
-
-    @Override
-    public boolean isAugmenting() {
-        return (operations & IS_AUGMENTING_BITS) != 0;
-    }
-
-    @Override
-    public boolean isAddedByUses() {
-        return (operations & IS_ADDED_BY_USES_BITS) != 0;
-    }
-
-    @VisibleForTesting
-    boolean contains(final CopyType type) {
-        return (operations & type.bit()) != 0;
-    }
-
-    @VisibleForTesting
-    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;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this).add("lastOperation", getLastOperation())
-                .add("operations", Arrays.stream(VALUES).filter(value -> (value.bit() & operations) != 0)
-                    .collect(Collectors.toList()))
-                .toString();
-    }
+@NonNullByDefault
+// FIXME: YANGTOOLS-1150: this should live in yang-reactor-api
+public interface CopyHistory extends CopyableNode {
+    /**
+     * Return the last copy operation in this history.
+     *
+     * @return Last {@link CopyType}
+     */
+    CopyType getLastOperation();
 }