BUG-7464: Do not check twice for prev to be null
[yangtools.git] / third-party / triemap / src / main / java / org / opendaylight / yangtools / triemap / INode.java
index 1c7167ebae6c6344ceab5ed9969845f287d5808b..2a59f01afea4e73a3eda6f00738851f10ace1975 100644 (file)
@@ -19,27 +19,14 @@ final class INode<K, V> extends INodeBase<K, V> {
     static final Object KEY_PRESENT = new Object ();
     static final Object KEY_ABSENT = new Object ();
 
-    static <K,V> INode<K,V> newRootNode() {
-        Gen gen = new Gen ();
-        CNode<K, V> cn = new CNode<> (0, new BasicNode[] {}, gen);
-        return new INode<>(cn, gen);
-    }
-
-    private INode(final MainNode<K, V> bn, final Gen g) {
-        super(g);
-        WRITE(bn);
-    }
-
-    INode(final Gen g) {
-        this(null, g);
-    }
-
-    void WRITE(final MainNode<K, V> nval) {
-        INodeBase.updater.set(this, nval);
-    }
+    /**
+     * 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();
 
-    boolean CAS(final MainNode<K, V> old, final MainNode<K, V> n) {
-        return INodeBase.updater.compareAndSet(this, old, n);
+    INode(final Gen gen, final MainNode<K, V> bn) {
+        super(gen, bn);
     }
 
     MainNode<K, V> gcasRead(final TrieMap<K, V> ct) {
@@ -47,8 +34,8 @@ final class INode<K, V> extends INodeBase<K, V> {
     }
 
     MainNode<K, V> GCAS_READ(final TrieMap<K, V> ct) {
-        MainNode<K, V> m = /* READ */mainnode;
-        MainNode<K, V> prevval = /* READ */m.prev;
+        MainNode<K, V> m = /* READ */ READ();
+        MainNode<K, V> prevval = /* READ */ m.READ_PREV();
         if (prevval == null) {
             return m;
         } else {
@@ -62,7 +49,7 @@ final class INode<K, V> extends INodeBase<K, V> {
                 return null;
             } else {
                 // complete the GCAS
-                MainNode<K, V> prev = /* READ */m.prev;
+                final MainNode<K, V> prev = /* READ */ m.READ_PREV();
                 INode<K, V> ctr = ct.readRoot(true);
 
                 if (prev == null) {
@@ -72,15 +59,15 @@ final class INode<K, V> extends INodeBase<K, V> {
                 if (prev instanceof FailedNode) {
                     // try to commit to previous value
                     FailedNode<K, V> fn = (FailedNode<K, V>) prev;
-                    if (CAS(m, fn.prev)) {
-                        return fn.prev;
+                    if (CAS(m, fn.READ_PREV())) {
+                        return fn.READ_PREV();
                     } else {
                         // Tailrec
                         // return GCAS_Complete (/* READ */mainnode, ct);
-                        m = /* READ */mainnode;
+                        m = /* READ */ READ();
                         continue;
                     }
-                } else if (prev instanceof MainNode) {
+                } else {
                     // Assume that you've read the root from the generation
                     // G.
                     // Assume that the snapshot algorithm is correct.
@@ -105,11 +92,10 @@ final class INode<K, V> extends INodeBase<K, V> {
                     } else {
                         // try to abort
                         m.CAS_PREV(prev, new FailedNode<>(prev));
-                        return GCAS_Complete(/* READ */mainnode, ct);
+                        return GCAS_Complete(/* READ */ READ(), ct);
                     }
                 }
             }
-            throw new RuntimeException ("Should not happen");
         }
     }
 
@@ -117,7 +103,7 @@ final class INode<K, V> extends INodeBase<K, V> {
         n.WRITE_PREV (old);
         if (CAS (old, n)) {
             GCAS_Complete (n, ct);
-            return /* READ */n.prev == null;
+            return /* READ */ n.READ_PREV() == null;
         } else {
             return false;
         }
@@ -128,16 +114,11 @@ final class INode<K, V> extends INodeBase<K, V> {
     }
 
     private INode<K, V> inode(final MainNode<K, V> cn) {
-        INode<K, V> nin = new INode<>(gen);
-        nin.WRITE(cn);
-        return nin;
+        return new INode<>(gen, cn);
     }
 
     INode<K, V> copyToGen(final Gen ngen, final TrieMap<K, V> ct) {
-        INode<K, V> nin = new INode<>(ngen);
-        MainNode<K, V> main = GCAS_READ(ct);
-        nin.WRITE(main);
-        return nin;
+        return new INode<>(ngen, GCAS_READ(ct));
     }
 
     /**
@@ -412,8 +393,7 @@ final class INode<K, V> extends INodeBase<K, V> {
                                 // Tailrec
                                 continue;
                             } else {
-                                return RESTART; // used to be throw
-                                // RestartException
+                                return RESTART; // used to be throw RestartException
                             }
                         }
                     } else if (sub instanceof SNode) {
@@ -432,7 +412,7 @@ final class INode<K, V> extends INodeBase<K, V> {
             } else if (m instanceof LNode) {
                 // 5) an l-node
                 Option<V> tmp = ((LNode<K, V>) m).get (k);
-                return (tmp instanceof Option) ? ((Option<V>) tmp) : null;
+                return (tmp != null) ? ((Option<V>) tmp) : null;
             }
 
             throw new RuntimeException ("Should not happen");