X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=third-party%2Ftriemap%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Ftriemap%2FINode.java;h=b86d4c4152003eaf0c54850f62ef83b5d4c49342;hb=edf71b3a0e03f13a9537076551718e2a995ecebe;hp=bc2a4d000a614d96bebbdcce550787f04de5d1a0;hpb=5c8c004ae6d36b84d017853e686be93a82d75f9d;p=yangtools.git diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/INode.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/INode.java index bc2a4d000a..b86d4c4152 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/INode.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/INode.java @@ -36,11 +36,11 @@ final class INode extends BasicNode { this.mainnode = mainnode; } - MainNode gcasRead(final TrieMap ct) { + MainNode gcasRead(final TrieMap ct) { return GCAS_READ(ct); } - MainNode GCAS_READ(final TrieMap ct) { + private MainNode GCAS_READ(final TrieMap ct) { MainNode m = /* READ */ mainnode; MainNode prevval = /* READ */ m.READ_PREV(); if (prevval == null) { @@ -50,7 +50,7 @@ final class INode extends BasicNode { return GCAS_Complete(m, ct); } - private MainNode GCAS_Complete(MainNode m, final TrieMap ct) { + private MainNode GCAS_Complete(MainNode m, final TrieMap ct) { while (true) { if (m == null) { return null; @@ -58,7 +58,7 @@ final class INode extends BasicNode { // complete the GCAS final MainNode prev = /* READ */ m.READ_PREV(); - final INode ctr = ct.readRoot(true); + final Gen rdgen = ct.readRoot(true).gen; if (prev == null) { return m; } @@ -83,7 +83,7 @@ final class INode extends BasicNode { // ==> if `ctr.gen` = `gen` then they are both equal to G. // ==> otherwise, we know that either `ctr.gen` > G, `gen` < G, // or both - if (ctr.gen == gen && !ct.isReadOnly()) { + if (rdgen == gen && !ct.isReadOnly()) { // try to commit if (m.CAS_PREV(prev, null)) { return m; @@ -101,7 +101,7 @@ final class INode extends BasicNode { } } - private boolean GCAS(final MainNode old, final MainNode n, final TrieMap ct) { + private boolean GCAS(final MainNode old, final MainNode n, final TrieMap ct) { n.WRITE_PREV(old); if (MAINNODE_UPDATER.compareAndSet(this, old, n)) { GCAS_Complete(n, ct); @@ -115,7 +115,7 @@ final class INode extends BasicNode { return new INode<>(gen, cn); } - INode copyToGen(final Gen ngen, final TrieMap ct) { + INode copyToGen(final Gen ngen, final TrieMap ct) { return new INode<>(ngen, GCAS_READ(ct)); } @@ -132,7 +132,7 @@ final class INode extends BasicNode { private boolean rec_insert(final K k, final V v, final int hc, final int lev, final INode parent, final Gen startgen, final TrieMap ct) { while (true) { - final MainNode m = GCAS_READ (ct); // use -Yinline! + final MainNode m = GCAS_READ(ct); // use -Yinline! if (m instanceof CNode) { // 1) a multiway node @@ -168,15 +168,17 @@ final class INode extends BasicNode { return GCAS (cn, nn, ct); } } else { - CNode rn = (cn.gen == gen) ? cn : cn.renewed(gen, ct); - MainNode ncnode = rn.insertedAt(pos, flag, new SNode<> (k, v, hc), gen); + final CNode rn = (cn.gen == gen) ? cn : cn.renewed(gen, ct); + final MainNode ncnode = rn.insertedAt(pos, flag, new SNode<>(k, v, hc), gen); return GCAS (cn, ncnode, ct); } } else if (m instanceof TNode) { clean(parent, ct, lev - 5); return false; } else if (m instanceof LNode) { - return insertln((LNode) m, k, v, ct); + final LNode ln = (LNode) m; + final LNodeEntry entry = ln.get(ct.equiv(), k); + return entry != null ? replaceln(ln, entry, v, ct) : insertln(ln, k, v, ct); } else { throw new IllegalStateException("Unhandled node " + m); } @@ -300,45 +302,32 @@ final class INode extends BasicNode { } else if (m instanceof LNode) { // 3) an l-node final LNode ln = (LNode) m; + final LNodeEntry entry = ln.get(ct.equiv(), k); + if (cond == null) { - final Optional optv = ln.get(ct.equiv(), k); - if (insertln(ln, k, v, ct)) { - return optv; + if (entry != null) { + return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null; } - return null; + + return insertln(ln, k, v, ct) ? Optional.empty() : null; } else if (cond == ABSENT) { - final Optional t = ln.get(ct.equiv(),k); - if (t.isPresent()) { - return t; + if (entry != null) { + return Optional.of(entry.value()); } - if (insertln(ln, k, v, ct)) { - return Optional.empty(); - } - return null; + + return insertln(ln, k, v, ct) ? Optional.empty() : null; } else if (cond == PRESENT) { - final Optional t = ln.get(ct.equiv(),k); - if (!t.isPresent()) { - return t; - } - if (insertln(ln, k, v, ct)) { - return t; + if (entry == null) { + return Optional.empty(); } - return null; - } else { - final Optional t = ln.get(ct.equiv(),k); - if (t.isPresent()) { - if (cond.equals(t.get())) { - if (insertln(ln, k, v, ct)) { - // Difference from Scala: we choose to reuse the object returned from LNode, - // as the identity of the value does not matter in this call graph. - return t; - } - return null; - } + return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null; + } else { + if (entry == null || !cond.equals(entry.value())) { + return Optional.empty(); } - return Optional.empty(); + return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null; } } else { throw new IllegalStateException("Unhandled node " + m); @@ -349,7 +338,11 @@ final class INode extends BasicNode { } private boolean insertln(final LNode ln, final K k, final V v, final TrieMap ct) { - return GCAS(ln, ln.addChild(ct.equiv(), k, v), ct); + return GCAS(ln, ln.insertChild(k, v), ct); + } + + private boolean replaceln(final LNode ln, final LNodeEntry entry, final V v, final TrieMap ct) { + return GCAS(ln, ln.replaceChild(entry, v), ct); } /** @@ -407,7 +400,8 @@ final class INode extends BasicNode { return cleanReadOnly((TNode) m, lev, parent, ct, k, hc); } else if (m instanceof LNode) { // 5) an l-node - return ((LNode) m).get(ct.equiv(), k).orElse(null); + final LNodeEntry entry = ((LNode) m).get(ct.equiv(), k); + return entry != null ? entry.value() : null; } else { throw new IllegalStateException("Unhandled node " + m); } @@ -433,19 +427,19 @@ final class INode extends BasicNode { /** * Removes the key associated with the given value. * - * @param v + * @param cond * if null, will remove the key regardless of the value; * otherwise removes only if binding contains that exact key * and value - * @return null if not successful, an Option[V] indicating the previous + * @return null if not successful, an Optional indicating the previous * value otherwise */ - Optional rec_remove(final K k, final V v, final int hc, final int lev, final INode parent, + Optional rec_remove(final K k, final Object cond, final int hc, final int lev, final INode parent, final TrieMap ct) { - return rec_remove(k, v, hc, lev, parent, gen, ct); + return rec_remove(k, cond, hc, lev, parent, gen, ct); } - private Optional rec_remove(final K k, final V v, final int hc, final int lev, final INode parent, + private Optional rec_remove(final K k, final Object cond, final int hc, final int lev, final INode parent, final Gen startgen, final TrieMap ct) { final MainNode m = GCAS_READ(ct); // use -Yinline! @@ -464,10 +458,10 @@ final class INode extends BasicNode { if (sub instanceof INode) { final INode in = (INode) sub; if (startgen == in.gen) { - res = in.rec_remove(k, v, hc, lev + 5, this, startgen, ct); + res = in.rec_remove(k, cond, hc, lev + 5, this, startgen, ct); } else { if (GCAS(cn, cn.renewed (startgen, ct), ct)) { - res = rec_remove(k, v, hc, lev, parent, startgen, ct); + res = rec_remove(k, cond, hc, lev, parent, startgen, ct); } else { res = null; } @@ -475,7 +469,7 @@ final class INode extends BasicNode { } else if (sub instanceof SNode) { final SNode sn = (SNode) sub; - if (sn.hc == hc && ct.equal(sn.k, k) && (v == null || v.equals(sn.v))) { + if (sn.hc == hc && ct.equal(sn.k, k) && (cond == null || cond.equals(sn.v))) { final MainNode ncn = cn.removedAt(pos, flag, gen).toContracted(lev); if (GCAS(cn, ncn, ct)) { res = Optional.of(sn.v); @@ -505,19 +499,19 @@ final class INode extends BasicNode { return null; } else if (m instanceof LNode) { final LNode ln = (LNode) m; - final Optional optv = ln.get(ct.equiv(), k); - - if (!optv.isPresent()) { + final LNodeEntry entry = ln.get(ct.equiv(), k); + if (entry == null) { // Key was not found, hence no modification is needed return Optional.empty(); } - if (v != null && !v.equals(optv.get())) { + final V value = entry.value(); + if (cond != null && !cond.equals(value)) { // Value does not match return Optional.empty(); } - return GCAS(ln, ln.removeChild(ct.equiv(), k, hc), ct) ? optv : null; + return GCAS(ln, ln.removeChild(entry, hc), ct) ? Optional.of(value) : null; } else { throw new IllegalStateException("Unhandled node " + m); } @@ -545,8 +539,8 @@ final class INode extends BasicNode { final BasicNode sub = cn.array[pos]; if (sub == this) { if (nonlive instanceof TNode) { - final TNode tn = (TNode) nonlive; - MainNode ncn = cn.updatedAt(pos, tn.copyUntombed(), gen).toContracted(lev - 5); + final TNode tn = (TNode) nonlive; + final MainNode ncn = cn.updatedAt(pos, tn.copyUntombed(), gen).toContracted(lev - 5); if (!parent.GCAS(cn, ncn, ct)) { if (ct.readRoot().gen == startgen) { // Tail recursion: cleanParent(nonlive, parent, ct, hc, lev, startgen); @@ -567,9 +561,8 @@ final class INode extends BasicNode { } } - int cachedSize(final TrieMap ct) { - MainNode m = GCAS_READ(ct); - return m.cachedSize(ct); + int cachedSize(final TrieMap ct) { + return GCAS_READ(ct).cachedSize(ct); } // /* this is a quiescent method! */