X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=third-party%2Ftriemap%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Ftriemap%2FCNode.java;fp=third-party%2Ftriemap%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Ftriemap%2FCNode.java;h=2b3885443032b74da154a6d999785d1d1cc79945;hb=38732c9e9834ba76f7cd1bae3d2d5e50e54a0bad;hp=76141ade5ad01b9cece84992b06b9a5b96a744d4;hpb=422344ce9059492bebc277edf22189cd3d4ec178;p=yangtools.git diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/CNode.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/CNode.java index 76141ade5a..2b38854430 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/CNode.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/CNode.java @@ -20,20 +20,15 @@ import static org.opendaylight.yangtools.triemap.Constants.LEVEL_BITS; import com.google.common.base.Verify; import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; final class CNode extends MainNode { - @SuppressWarnings("rawtypes") - private static final AtomicIntegerFieldUpdater CSIZE_UPDATER = AtomicIntegerFieldUpdater.newUpdater( - CNode.class, "csize"); - private static final BasicNode[] EMPTY_ARRAY = new BasicNode[0]; - private static final int NO_SIZE = -1; final int bitmap; final BasicNode[] array; final Gen gen; + // Since concurrent computation should lead to same results we can update this field without any synchronization. private volatile int csize = NO_SIZE; private CNode(final Gen gen, final int bitmap, final BasicNode... array) { @@ -68,20 +63,15 @@ final class CNode extends MainNode { return xidx < yidx ? new CNode<>(gen, bmp, x, y) : new CNode<>(gen, bmp, y, x); } - // this should only be called from within read-only snapshots @Override - int cachedSize(final TrieMap ct) { - int sz = csize; - if (sz == NO_SIZE) { - // We have not computed the size yet, do that now - sz = computeSize(ct); - if (!CSIZE_UPDATER.compareAndSet(this, NO_SIZE, sz)) { - // We have been pre-empted by some else: read the result - sz = csize; - } - } + int trySize() { + return csize; + } - return sz; + @Override + int size(final ImmutableTrieMap ct) { + int sz; + return (sz = csize) != NO_SIZE ? sz : (csize = computeSize(ct)); } // lends itself towards being parallelizable by choosing @@ -89,7 +79,7 @@ final class CNode extends MainNode { // => if there are concurrent size computations, they start // at different positions, so they are more likely to // to be independent - private int computeSize(final TrieMap ct) { + private int computeSize(final ImmutableTrieMap ct) { final int len = array.length; switch (len) { case 0: @@ -109,11 +99,11 @@ final class CNode extends MainNode { } } - private static int elementSize(final BasicNode elem, final TrieMap ct) { + private static int elementSize(final BasicNode elem, final ImmutableTrieMap ct) { if (elem instanceof SNode) { return 1; } else if (elem instanceof INode) { - return ((INode) elem).cachedSize(ct); + return ((INode) elem).size(ct); } else { throw new IllegalStateException("Unhandled element " + elem); }