From 445b30f0fe3968e63d817c86260118fef893eec8 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Sat, 31 Dec 2016 19:59:37 +0100 Subject: [PATCH] BUG-7464: Migrate to use java.util.Optional Standard Java provides better interface than the custom-ported Option/None/Some. Migrate to use it. Change-Id: I6f4892d224bc8cbc5c37549cf7a54df86f97f207 Signed-off-by: Robert Varga --- .../opendaylight/yangtools/triemap/INode.java | 80 +++++++++---------- .../opendaylight/yangtools/triemap/LNode.java | 3 +- .../yangtools/triemap/ListMap.java | 9 ++- .../opendaylight/yangtools/triemap/None.java | 30 ------- .../yangtools/triemap/Option.java | 42 ---------- .../opendaylight/yangtools/triemap/Some.java | 40 ---------- .../yangtools/triemap/TrieMap.java | 55 ++++--------- .../yangtools/triemap/ListMapTest.java | 5 +- 8 files changed, 64 insertions(+), 200 deletions(-) delete mode 100644 third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/None.java delete mode 100644 third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Option.java delete mode 100644 third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Some.java 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 c1975ecaf4..ab01536aad 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 @@ -15,6 +15,8 @@ */ package org.opendaylight.yangtools.triemap; +import java.util.Optional; + final class INode extends INodeBase { static final Object KEY_PRESENT = new Object (); static final Object KEY_ABSENT = new Object (); @@ -186,7 +188,7 @@ final class INode extends INodeBase { * @return null if unsuccessful, Option[V] otherwise (indicating * previous value bound to the key) */ - Option rec_insertif(final K k, final V v, final int hc, final Object cond, final int lev, + Optional rec_insertif(final K k, final V v, final int hc, final Object cond, final int lev, final INode parent, final Gen startgen, final TrieMap ct) { while (true) { final MainNode m = GCAS_READ(ct); // use -Yinline! @@ -220,7 +222,7 @@ final class INode extends INodeBase { if (cond == null) { if (sn.hc == hc && ct.equal(sn.k, k)) { if (GCAS(cn, cn.updatedAt(pos, new SNode<>(k, v, hc), gen), ct)) { - return Option.makeOption(sn.v); + return Optional.of(sn.v); } return null; @@ -230,56 +232,56 @@ final class INode extends INodeBase { final MainNode nn = rn.updatedAt(pos, inode (CNode.dual(sn, sn.hc, new SNode<>(k, v, hc), hc, lev + 5, gen)), gen); if (GCAS(cn, nn, ct)) { - return Option.makeOption(); // None; + return Optional.empty(); } return null; } else if (cond == INode.KEY_ABSENT) { if (sn.hc == hc && ct.equal(sn.k, k)) { - return Option.makeOption(sn.v); + return Optional.of(sn.v); } final CNode rn = (cn.gen == gen) ? cn : cn.renewed(gen, ct); final MainNode nn = rn.updatedAt(pos, inode (CNode.dual(sn, sn.hc, new SNode<>(k, v, hc), hc, lev + 5, gen)), gen); if (GCAS(cn, nn, ct)) { - return Option.makeOption(); // None + return Optional.empty(); } return null; } else if (cond == INode.KEY_PRESENT) { if (sn.hc == hc && ct.equal(sn.k, k)) { if (GCAS(cn, cn.updatedAt(pos, new SNode<>(k, v, hc), gen), ct)) { - return Option.makeOption(sn.v); + return Optional.of(sn.v); } return null; } - return Option.makeOption();// None; + return Optional.empty(); } else { if (sn.hc == hc && ct.equal(sn.k, k) && cond.equals(sn.v)) { if (GCAS(cn, cn.updatedAt(pos, new SNode<>(k, v, hc), gen), ct)) { - return Option.makeOption(sn.v); + return Optional.of(sn.v); } return null; } - return Option.makeOption(); // None + return Optional.empty(); } } } else if (cond == null || cond == INode.KEY_ABSENT) { final CNode rn = (cn.gen == gen) ? cn : cn.renewed(gen, ct); final CNode ncnode = rn.insertedAt (pos, flag, new SNode<>(k, v, hc), gen); if (GCAS(cn, ncnode, ct)) { - return Option.makeOption(); // None + return Optional.empty(); } return null; } else if (cond == INode.KEY_PRESENT) { - return Option.makeOption(); // None; + return Optional.empty(); } else { - return Option.makeOption(); // None + return Optional.empty(); } } else if (m instanceof TNode) { clean(parent, ct, lev - 5); @@ -288,23 +290,23 @@ final class INode extends INodeBase { // 3) an l-node final LNode ln = (LNode) m; if (cond == null) { - final Option optv = ln.get(k); + final Optional optv = ln.get(k); if (insertln(ln, k, v, ct)) { return optv; } return null; } else if (cond == INode.KEY_ABSENT) { - final Option t = ln.get(k); - if (t.nonEmpty()) { + final Optional t = ln.get(k); + if (t.isPresent()) { return t; } if (insertln(ln, k, v, ct)) { - return Option.makeOption();// None + return Optional.empty(); } return null; } else if (cond == INode.KEY_PRESENT) { - final Option t = ln.get(k); - if (!t.nonEmpty()) { + final Optional t = ln.get(k); + if (!t.isPresent()) { return t; } if (insertln(ln, k, v, ct)) { @@ -312,10 +314,9 @@ final class INode extends INodeBase { } return null; } else { - final Option t = ln.get(k); - if (t instanceof Some) { - final Some s = (Some) t; - if (cond.equals(s.get())) { + final Optional t = ln.get(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. @@ -326,7 +327,7 @@ final class INode extends INodeBase { } } - return Option.makeOption(); + return Optional.empty(); } } else { throw new IllegalStateException("Unhandled node " + m); @@ -427,7 +428,7 @@ final class INode extends INodeBase { * @return null if not successful, an Option[V] indicating the previous * value otherwise */ - Option rec_remove(final K k, final V v, final int hc, final int lev, final INode parent, + Optional rec_remove(final K k, final V v, final int hc, final int lev, final INode parent, final Gen startgen, final TrieMap ct) { final MainNode m = GCAS_READ(ct); // use -Yinline! @@ -437,12 +438,12 @@ final class INode extends INodeBase { final int bmp = cn.bitmap; final int flag = 1 << idx; if ((bmp & flag) == 0) { - return Option.makeOption(); + return Optional.empty(); } final int pos = Integer.bitCount(bmp & (flag - 1)); final BasicNode sub = cn.array[pos]; - Option res = null; + Optional res = null; if (sub instanceof INode) { final INode in = (INode) sub; if (startgen == in.gen) { @@ -460,16 +461,16 @@ final class INode extends INodeBase { if (sn.hc == hc && ct.equal(sn.k, k) && (v == null || v.equals(sn.v))) { final MainNode ncn = cn.removedAt(pos, flag, gen).toContracted(lev); if (GCAS(cn, ncn, ct)) { - res = Option.makeOption(sn.v); + res = Optional.of(sn.v); } else { res = null; } } else { - res = Option.makeOption (); + res = Optional.empty(); } } - if (res instanceof None || (res == null)) { + if (res == null || !res.isPresent()) { return res; } @@ -488,7 +489,7 @@ final class INode extends INodeBase { } else if (m instanceof LNode) { final LNode ln = (LNode) m; if (v == null) { - final Option optv = ln.get(k); + final Optional optv = ln.get(k); final MainNode nn = ln.removed(k, ct); if (GCAS(ln, nn, ct)) { return optv; @@ -497,21 +498,18 @@ final class INode extends INodeBase { return null; } - final Option tmp = ln.get(k); - if (tmp instanceof Some) { - final Some tmp1 = (Some) tmp; - if (v.equals(tmp1.get())) { - final MainNode nn = ln.removed(k, ct); - if (GCAS(ln, nn, ct)) { - return tmp; - } - - return null; + final Optional tmp = ln.get(k); + if (tmp.isPresent() && v.equals(tmp.get())) { + final MainNode nn = ln.removed(k, ct); + if (GCAS(ln, nn, ct)) { + return tmp; } + + return null; } // Key not found or value does not match: we have not removed anything - return Option.makeOption(); + return Optional.empty(); } else { throw new IllegalStateException("Unhandled node " + m); } diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/LNode.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/LNode.java index 1bad144a40..0fec28954a 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/LNode.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/LNode.java @@ -17,6 +17,7 @@ package org.opendaylight.yangtools.triemap; import java.util.Iterator; import java.util.Map.Entry; +import java.util.Optional; final class LNode extends MainNode { private final ListMap listmap; @@ -46,7 +47,7 @@ final class LNode extends MainNode { return new TNode<>(kv.getKey(), kv.getValue(), ct.computeHash(kv.getKey())); } - Option get(final K k) { + Optional get(final K k) { return listmap.get(k); } diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/ListMap.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/ListMap.java index 9978b5f627..fba40ded2c 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/ListMap.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/ListMap.java @@ -19,6 +19,7 @@ import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Iterator; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.Optional; /** * Mimic immutable ListMap in Scala @@ -56,19 +57,19 @@ final class ListMap { return sz; } - Option get(final K key) { + Optional get(final K key) { if (key.equals(k)) { - return Option.makeOption(v); + return Optional.of(v); } // We do not perform recursion on purpose here, so we do not run out of stack if the key hashing fails. for (ListMap m = next; m != null; m = m.next) { if (key.equals(m.k)) { - return Option.makeOption(m.v); + return Optional.of(m.v); } } - return Option.makeOption(); + return Optional.empty(); } ListMap add(final K key, final V value) { diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/None.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/None.java deleted file mode 100644 index cef3a0cdff..0000000000 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/None.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.opendaylight.yangtools.triemap; - -/** - * Mimic None in Scala - * - * @author Roman Levenstein - * - * @param - */ -final class None extends Option { - @Override - boolean nonEmpty() { - return false; - } -} diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Option.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Option.java deleted file mode 100644 index 36b8d0eab7..0000000000 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Option.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.opendaylight.yangtools.triemap; - -/** - * Mimic Option in Scala - * - * @author Roman Levenstein - * - * @param - */ -abstract class Option { - private static final None NONE = new None<>(); - - static Option makeOption(final V o) { - if (o != null) { - return new Some<>(o); - } - - return makeOption(); - } - - @SuppressWarnings("unchecked") - static Option makeOption() { - return (Option) NONE; - } - - abstract boolean nonEmpty(); -} diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Some.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Some.java deleted file mode 100644 index e81df3dcd8..0000000000 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/Some.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.opendaylight.yangtools.triemap; - -/** - * Mimic Some in Scala - * - * @author Roman Levenstein - * - * @param - */ -final class Some extends Option{ - private final V value; - - Some(final V v) { - value = v; - } - - V get() { - return value; - } - - @Override - boolean nonEmpty () { - return value != null; - } -} diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java index d64875007e..676cd7137c 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java @@ -27,6 +27,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; @@ -185,10 +186,10 @@ public final class TrieMap extends AbstractMap implements Concurrent } } - private Option insertifhc(final K k, final int hc, final V v, final Object cond) { + private Optional insertifhc(final K k, final int hc, final V v, final Object cond) { while (true) { final INode r = RDCSS_READ_ROOT(); - final Option ret = r.rec_insertif(k, v, hc, cond, 0, null, r.gen, this); + final Optional ret = r.rec_insertif(k, v, hc, cond, 0, null, r.gen, this); if (ret != null) { return ret; } @@ -209,10 +210,10 @@ public final class TrieMap extends AbstractMap implements Concurrent } } - private Option removehc(final K k, final V v, final int hc) { + private Optional removehc(final K k, final V v, final int hc) { while (true) { final INode r = RDCSS_READ_ROOT(); - final Option res = r.rec_remove(k, v, hc, 0, null, r.gen, this); + final Optional res = r.rec_remove(k, v, hc, 0, null, r.gen, this); if (res != null) { return res; } @@ -315,13 +316,11 @@ public final class TrieMap extends AbstractMap implements Concurrent final int hc = computeHash (k); // return (V) lookuphc (k, hc); final Object o = lookuphc (k, hc); - if (o instanceof Some) { - return ((Some)o).get (); - } else if (o instanceof None) { - return null; - } else { - return (V)o; + if (o instanceof Optional) { + return ((Optional) o).orElse(null); } + + return (V)o; } @Override @@ -333,13 +332,7 @@ public final class TrieMap extends AbstractMap implements Concurrent public V put(final K key, final V value) { ensureReadWrite(); final int hc = computeHash(key); - final Option ov = insertifhc (key, hc, value, null); - if (ov instanceof Some) { - Some sv = (Some)ov; - return sv.get (); - } - - return null; + return insertifhc (key, hc, value, null).orElse(null); } TrieMap add(final K k, final V v) { @@ -352,53 +345,35 @@ public final class TrieMap extends AbstractMap implements Concurrent public V remove(final Object k) { ensureReadWrite(); final int hc = computeHash ((K)k); - final Option ov = removehc ((K)k, (V) null, hc); - if (ov instanceof Some) { - Some sv = (Some)ov; - return sv.get(); - } - - return null; + return removehc ((K)k, (V) null, hc).orElse(null); } @Override public V putIfAbsent(final K k, final V v) { ensureReadWrite(); final int hc = computeHash (k); - final Option ov = insertifhc (k, hc, v, INode.KEY_ABSENT); - if (ov instanceof Some) { - Some sv = (Some)ov; - return sv.get(); - } - - return null; + return insertifhc (k, hc, v, INode.KEY_ABSENT).orElse(null); } @Override public boolean remove(final Object k, final Object v) { ensureReadWrite(); final int hc = computeHash ((K)k); - return removehc((K)k, (V)v, hc).nonEmpty(); + return removehc((K)k, (V)v, hc).isPresent(); } @Override public boolean replace(final K k, final V oldvalue, final V newvalue) { ensureReadWrite(); final int hc = computeHash (k); - return insertifhc (k, hc, newvalue, oldvalue).nonEmpty(); + return insertifhc (k, hc, newvalue, oldvalue).isPresent(); } @Override public V replace(final K k, final V v) { ensureReadWrite(); final int hc = computeHash (k); - final Option ov = insertifhc (k, hc, v, INode.KEY_PRESENT); - if (ov instanceof Some) { - Some sv = (Some)ov; - return sv.get(); - } - - return null; + return insertifhc (k, hc, v, INode.KEY_PRESENT).orElse(null); } /*** diff --git a/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java b/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java index f6afabf30c..6230134d97 100644 --- a/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java +++ b/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java @@ -17,6 +17,7 @@ package org.opendaylight.yangtools.triemap; import static org.junit.Assert.assertFalse; +import java.util.Optional; import org.junit.Test; public class ListMapTest { @@ -33,8 +34,8 @@ public class ListMapTest { map = map.add(i, Boolean.TRUE); } - final Option ret = map.get(0); - assertFalse(ret.nonEmpty()); + final Optional ret = map.get(0); + assertFalse(ret.isPresent()); } } -- 2.36.6