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;h=9b20a1bb03103df1ace56a6c1b14059c4a725303;hb=88a92ba9395d82a38dd2250451a2c88bfe9ed63f;hp=581594346e0728aa21f1a4c313cc5afad63ad580;hpb=b08662fc364d3469e4aac44ae780a347224399f4;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 581594346e..9b20a1bb03 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 @@ -15,31 +15,69 @@ */ package org.opendaylight.yangtools.triemap; -final class CNode extends CNodeBase { +import com.google.common.base.Verify; +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; - CNode(final int bitmap, final BasicNode[] array, final Gen gen) { + private volatile int csize = NO_SIZE; + + private CNode(final Gen gen, final int bitmap, final BasicNode... array) { this.bitmap = bitmap; this.array = array; this.gen = gen; } + CNode(final Gen gen) { + this(gen, 0, EMPTY_ARRAY); + } + + static MainNode dual(final SNode x, final K k, final V v, final int hc, final int lev, + final Gen gen) { + return dual(x, x.hc, new SNode<>(k, v, hc), hc, lev, gen); + } + + private static MainNode dual(final SNode x, final int xhc, final SNode y, final int yhc, + final int lev, final Gen gen) { + if (lev >= 35) { + return new LNode<>(x.k, x.v, y.k, y.v); + } + + final int xidx = (xhc >>> lev) & 0x1f; + final int yidx = (yhc >>> lev) & 0x1f; + final int bmp = (1 << xidx) | (1 << yidx); + + if (xidx == yidx) { + return new CNode<>(gen, bmp, new INode<>(gen, dual(x, xhc, y, yhc, lev + 5, gen))); + } + + 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) { - final int currsz = READ_SIZE(); - if (currsz != -1) { - return currsz; + 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; + } } - final int sz = computeSize(ct); - while (READ_SIZE () == -1) { - CAS_SIZE (-1, sz); - } - return READ_SIZE (); + return sz; } // lends itself towards being parallelizable by choosing @@ -47,7 +85,7 @@ final class CNode extends CNodeBase { // => 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 TrieMap ct) { int i = 0; int sz = 0; // final int offset = (array.length > 0) ? @@ -64,7 +102,7 @@ final class CNode extends CNodeBase { if (elem instanceof SNode) { sz += 1; } else if (elem instanceof INode) { - sz += ((INode) elem).cachedSize (ct); + sz += ((INode) elem).cachedSize(ct); } i += 1; } @@ -76,7 +114,7 @@ final class CNode extends CNodeBase { BasicNode[] narr = new BasicNode[len]; System.arraycopy(array, 0, narr, 0, len); narr[pos] = nn; - return new CNode<>(bitmap, narr, gen); + return new CNode<>(gen, bitmap, narr); } CNode removedAt(final int pos, final int flag, final Gen gen) { @@ -85,7 +123,7 @@ final class CNode extends CNodeBase { BasicNode[] narr = new BasicNode[len - 1]; System.arraycopy(arr, 0, narr, 0, pos); System.arraycopy(arr, pos + 1, narr, pos, len - pos - 1); - return new CNode<>(bitmap ^ flag, narr, gen); + return new CNode<>(gen, bitmap ^ flag, narr); } CNode insertedAt(final int pos, final int flag, final BasicNode nn, final Gen gen) { @@ -95,7 +133,7 @@ final class CNode extends CNodeBase { System.arraycopy(array, 0, narr, 0, pos); narr [pos] = nn; System.arraycopy(array, pos, narr, pos + 1, len - pos); - return new CNode<>(bmp | flag, narr, gen); + return new CNode<>(gen, bmp | flag, narr); } /** @@ -104,42 +142,30 @@ final class CNode extends CNodeBase { */ CNode renewed(final Gen ngen, final TrieMap ct) { int i = 0; - BasicNode[] arr = array; - int len = arr.length; - BasicNode[] narr = new BasicNode[len]; + final BasicNode[] arr = array; + final int len = arr.length; + final BasicNode[] narr = new BasicNode[len]; while (i < len) { - BasicNode elem = arr[i]; + final BasicNode elem = arr[i]; if (elem instanceof INode) { - INode in = (INode) elem; - narr [i] = in.copyToGen(ngen, ct); - } else if (elem instanceof BasicNode) { - narr [i] = elem; + narr[i] = ((INode) elem).copyToGen(ngen, ct); + } else if (elem != null) { + narr[i] = elem; } i += 1; } - return new CNode<>(bitmap, narr, ngen); - } - - private BasicNode resurrect(final INode inode, final Object inodemain) { - if (inodemain instanceof TNode) { - TNode tn = (TNode) inodemain; - return tn.copyUntombed(); - } - - return inode; + return new CNode<>(ngen, bitmap, narr); } MainNode toContracted(final int lev) { if (array.length == 1 && lev > 0) { - if (array [0] instanceof SNode) { - SNode sn = (SNode) array[0]; - return sn.copyTombed(); - } else { - return this; + if (array[0] instanceof SNode) { + return ((SNode) array[0]).copyTombed(); } - } else { return this; } + + return this; } // - if the branching factor is 1 for this CNode, and the child @@ -148,7 +174,7 @@ final class CNode extends CNodeBase { // returns the version of this node with at least some null-inodes // removed (those existing when the op began) // - if there are only null-i-nodes below, returns null - MainNode toCompressed(final TrieMap ct, final int lev, final Gen gen) { + MainNode toCompressed(final TrieMap ct, final int lev, final Gen gen) { int bmp = bitmap; int i = 0; BasicNode[] arr = array; @@ -156,17 +182,20 @@ final class CNode extends CNodeBase { while (i < arr.length) { // construct new bitmap BasicNode sub = arr[i]; if (sub instanceof INode) { - INode in = (INode) sub; - MainNode inodemain = in.gcasRead (ct); - assert (inodemain != null); - tmparray [i] = resurrect (in, inodemain); + final INode in = (INode) sub; + final MainNode inodemain = Verify.verifyNotNull(in.gcasRead(ct)); + tmparray [i] = resurrect(in, inodemain); } else if (sub instanceof SNode) { tmparray [i] = sub; } i += 1; } - return new CNode (bmp, tmparray, gen).toContracted (lev); + return new CNode(gen, bmp, tmparray).toContracted(lev); + } + + private static BasicNode resurrect(final INode inode, final MainNode inodemain) { + return inodemain instanceof TNode ? ((TNode) inodemain).copyUntombed() : inode; } @Override @@ -207,26 +236,4 @@ final class CNode extends CNodeBase { // elems.sorted.mkString(", ")) return "CNode"; } - - static MainNode dual(final SNode x, final int xhc, final SNode y, final int yhc, - final int lev, final Gen gen) { - if (lev < 35) { - int xidx = (xhc >>> lev) & 0x1f; - int yidx = (yhc >>> lev) & 0x1f; - int bmp = (1 << xidx) | (1 << yidx); - - if (xidx == yidx) { - INode subinode = new INode<>(gen, dual(x, xhc, y, yhc, lev + 5, gen)); - return new CNode<>(bmp, new BasicNode[] { subinode }, gen); - } else { - if (xidx < yidx) { - return new CNode<>(bmp, new BasicNode[] { x, y }, gen); - } else { - return new CNode<>(bmp, new BasicNode[] { y, x }, gen); - } - } - } else { - return new LNode<>(x.k, x.v, y.k, y.v); - } - } }