BUG-7464: Encapsupate special objects.
[yangtools.git] / third-party / triemap / src / main / java / org / opendaylight / yangtools / triemap / INode.java
index 2e8efe65241282beb0e125e9e6a232d032ffa2b7..752dfb9874ed9a4b1e24c77901c653d02e564b60 100644 (file)
  */
 package org.opendaylight.yangtools.triemap;
 
+import static org.opendaylight.yangtools.triemap.LookupResult.RESTART;
+import static org.opendaylight.yangtools.triemap.PresencePredicate.ABSENT;
+import static org.opendaylight.yangtools.triemap.PresencePredicate.PRESENT;
+
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 
 final class INode<K, V> extends BasicNode {
-    static final Object KEY_PRESENT = new Object ();
-    static final Object KEY_ABSENT = new Object ();
-
-    /**
-     * Virtual result for lookup methods indicating that the lookup needs to be restarted. This is a faster version
-     * of throwing a checked exception to control the restart.
-     */
-    static final Object RESTART = new Object();
-
     @SuppressWarnings("rawtypes")
     private static final AtomicReferenceFieldUpdater<INode, MainNode> MAINNODE_UPDATER =
             AtomicReferenceFieldUpdater.newUpdater(INode.class, MainNode.class, "mainnode");
 
-    public final Gen gen;
+    private final Gen gen;
 
     private volatile MainNode<K, V> mainnode;
 
@@ -88,7 +83,7 @@ final class INode<K, V> 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.nonReadOnly()) {
+            if (ctr.gen == gen && !ct.isReadOnly()) {
                 // try to commit
                 if (m.CAS_PREV(prev, null)) {
                     return m;
@@ -129,8 +124,13 @@ final class INode<K, V> extends BasicNode {
      *
      * @return true if successful, false otherwise
      */
-    boolean rec_insert(final K k, final V v, final int hc, final int lev, final INode<K, V> parent, final Gen startgen,
+    boolean rec_insert(final K k, final V v, final int hc, final int lev, final INode<K, V> parent,
             final TrieMap<K, V> ct) {
+        return rec_insert(k, v, hc, lev, parent, gen, ct);
+    }
+
+    private boolean rec_insert(final K k, final V v, final int hc, final int lev, final INode<K, V> parent,
+            final Gen startgen, final TrieMap<K, V> ct) {
         while (true) {
             final MainNode<K, V> m = GCAS_READ (ct); // use -Yinline!
 
@@ -199,6 +199,11 @@ final class INode<K, V> extends BasicNode {
      *         previous value bound to the key)
      */
     Optional<V> rec_insertif(final K k, final V v, final int hc, final Object cond, final int lev,
+            final INode<K, V> parent, final TrieMap<K, V> ct) {
+        return rec_insertif(k, v, hc, cond, lev, parent, gen, ct);
+    }
+
+    private Optional<V> rec_insertif(final K k, final V v, final int hc, final Object cond, final int lev,
             final INode<K, V> parent, final Gen startgen, final TrieMap<K, V> ct) {
         while (true) {
             final MainNode<K, V> m = GCAS_READ(ct); // use -Yinline!
@@ -246,7 +251,7 @@ final class INode<K, V> extends BasicNode {
                             }
 
                             return null;
-                        } else if (cond == INode.KEY_ABSENT) {
+                        } else if (cond == ABSENT) {
                             if (sn.hc == hc && ct.equal(sn.k, k)) {
                                 return Optional.of(sn.v);
                             }
@@ -259,7 +264,7 @@ final class INode<K, V> extends BasicNode {
                             }
 
                             return null;
-                        } else if (cond == INode.KEY_PRESENT) {
+                        } else if (cond == PRESENT) {
                             if (sn.hc == hc && ct.equal(sn.k, k)) {
                                 if (GCAS(cn, cn.updatedAt(pos, new SNode<>(k, v, hc), gen), ct)) {
                                     return Optional.of(sn.v);
@@ -280,7 +285,7 @@ final class INode<K, V> extends BasicNode {
                             return Optional.empty();
                         }
                     }
-                } else if (cond == null || cond == INode.KEY_ABSENT) {
+                } else if (cond == null || cond == ABSENT) {
                     final CNode<K, V> rn = (cn.gen == gen) ? cn : cn.renewed(gen, ct);
                     final CNode<K, V> ncnode = rn.insertedAt (pos, flag, new SNode<>(k, v, hc), gen);
                     if (GCAS(cn, ncnode, ct)) {
@@ -288,8 +293,6 @@ final class INode<K, V> extends BasicNode {
                     }
 
                     return null;
-                } else if (cond == INode.KEY_PRESENT) {
-                    return Optional.empty();
                 } else {
                     return Optional.empty();
                 }
@@ -305,7 +308,7 @@ final class INode<K, V> extends BasicNode {
                         return optv;
                     }
                     return null;
-                } else if (cond == INode.KEY_ABSENT) {
+                } else if (cond == ABSENT) {
                     final Optional<V> t = ln.get(k);
                     if (t.isPresent()) {
                         return t;
@@ -314,7 +317,7 @@ final class INode<K, V> extends BasicNode {
                         return Optional.empty();
                     }
                     return null;
-                } else if (cond == INode.KEY_PRESENT) {
+                } else if (cond == PRESENT) {
                     final Optional<V> t = ln.get(k);
                     if (!t.isPresent()) {
                         return t;
@@ -358,7 +361,11 @@ final class INode<K, V> extends BasicNode {
      * @return null if no value has been found, RESTART if the operation
      *         wasn't successful, or any other value otherwise
      */
-    Object rec_lookup(final K k, final int hc, final int lev, final INode<K, V> parent, final Gen startgen,
+    Object rec_lookup(final K k, final int hc, final int lev, final INode<K, V> parent, final TrieMap<K, V> ct) {
+        return rec_lookup(k, hc, lev, parent, gen, ct);
+    }
+
+    private Object rec_lookup(final K k, final int hc, final int lev, final INode<K, V> parent, final Gen startgen,
             final TrieMap<K, V> ct) {
         while (true) {
             final MainNode<K, V> m = GCAS_READ(ct); // use -Yinline!
@@ -388,7 +395,6 @@ final class INode<K, V> extends BasicNode {
                         continue;
                     }
 
-                    // used to be throw RestartException
                     return RESTART;
                 } else if (sub instanceof SNode) {
                     // 2) singleton node
@@ -415,17 +421,16 @@ final class INode<K, V> extends BasicNode {
 
     private Object cleanReadOnly(final TNode<K, V> tn, final int lev, final INode<K, V> parent,
             final TrieMap<K, V> ct, final K k, final int hc) {
-        if (ct.nonReadOnly()) {
-            // used to be throw RestartException
-            clean(parent, ct, lev - 5);
-            return RESTART;
-        }
+        if (ct.isReadOnly()) {
+            if (tn.hc == hc && ct.equal(tn.k, k)) {
+                return tn.v;
+            }
 
-        if (tn.hc == hc && ct.equal(tn.k, k)) {
-            return tn.v;
+            return null;
         }
 
-        return null;
+        clean(parent, ct, lev - 5);
+        return RESTART;
     }
 
     /**
@@ -439,6 +444,11 @@ final class INode<K, V> extends BasicNode {
      *         value otherwise
      */
     Optional<V> rec_remove(final K k, final V v, final int hc, final int lev, final INode<K, V> parent,
+            final TrieMap<K, V> ct) {
+        return rec_remove(k, v, hc, lev, parent, gen, ct);
+    }
+
+    private Optional<V> rec_remove(final K k, final V v, final int hc, final int lev, final INode<K, V> parent,
             final Gen startgen, final TrieMap<K, V> ct) {
         final MainNode<K, V> m = GCAS_READ(ct); // use -Yinline!