BUG-7464: Use Guava-like Equivalence instead of custom interfaces
[yangtools.git] / third-party / triemap / src / main / java / org / opendaylight / yangtools / triemap / TrieMap.java
index ce9409e8c0999ede623be99e17cda8344c373352..66019e3f27092a5dafdfbf800529c177b6f32a0e 100644 (file)
@@ -27,7 +27,6 @@ import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -88,37 +87,20 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
         }
     }
 
-    private final Hashing<K> hashingobj;
-    private final Equiv<K> equalityobj;
-
-    Hashing<K> hashing () {
-        return hashingobj;
-    }
-
-    Equiv<K> equality () {
-        return equalityobj;
-    }
+    private final Equivalence<? super K> equiv;
 
     private transient volatile Object root;
     private final transient boolean readOnly;
 
-    TrieMap (final Hashing<K> hashf, final Equiv<K> ef, final boolean readOnly) {
-        this.hashingobj = hashf;
-        this.equalityobj = ef;
-        this.readOnly = readOnly;
-    }
-
-    TrieMap (final Object r, final Hashing<K> hashf, final Equiv<K> ef, final boolean readOnly) {
-        this(hashf, ef, readOnly);
+    TrieMap (final Object r, final Equivalence<? super K> equiv, final boolean readOnly) {
         this.root = r;
-    }
+        this.equiv = equiv;
+        this.readOnly = readOnly;
 
-    public TrieMap (final Hashing<K> hashf, final Equiv<K> ef) {
-        this(INode.newRootNode(), hashf, ef, false);
     }
 
-    public TrieMap () {
-        this (new Hashing.Default<K>(), Equiv.universal);
+    public TrieMap() {
+        this(newRootNode(), Equivalence.equals(), false);
     }
 
     /* internal methods */
@@ -155,6 +137,11 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
     // } while (obj != TrieMapSerializationEnd);
     // }
 
+    private static <K,V> INode<K,V> newRootNode() {
+        final Gen gen = new Gen();
+        return new INode<>(gen, new CNode<>(gen));
+    }
+
     final boolean CAS_ROOT (final Object ov, final Object nv) {
         if (isReadOnly()) {
             throw new IllegalStateException("Attempted to modify a read-only snapshot");
@@ -269,17 +256,15 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
         }
     }
 
-    private Object lookuphc (final K k, final int hc) {
+    private Object lookuphc(final K k, final int hc) {
         while (true) {
-            INode<K, V> r = RDCSS_READ_ROOT ();
-            Object res = r.rec_lookup (k, hc, 0, null, r.gen, this);
-            if (res == INodeBase.RESTART) {
-                // return lookuphc (k, hc);
-                // tailrec
-                continue;
-            } else {
+            final INode<K, V> r = RDCSS_READ_ROOT ();
+            final Object res = r.rec_lookup(k, hc, 0, null, r.gen, this);
+            if (!INode.RESTART.equals(res)) {
                 return res;
             }
+
+            // Tail recursion: lookuphc(k, hc)
         }
     }
 
@@ -348,7 +333,7 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
             INode<K, V> r = RDCSS_READ_ROOT ();
             final MainNode<K, V> expmain = r.gcasRead (this);
             if (RDCSS_ROOT (r, expmain, r.copyToGen (new Gen (), this))) {
-                return new TrieMap<> (r.copyToGen (new Gen (), this), hashing (), equality (), readOnly);
+                return new TrieMap<> (r.copyToGen (new Gen (), this), equiv, readOnly);
             } else {
                 // return snapshot ();
                 // tailrec
@@ -380,7 +365,7 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
             INode<K, V> r = RDCSS_READ_ROOT ();
             MainNode<K, V> expmain = r.gcasRead (this);
             if (RDCSS_ROOT (r, expmain, r.copyToGen (new Gen (), this))) {
-                return new TrieMap<> (r, hashing (), equality (), true);
+                return new TrieMap<> (r, equiv, true);
             } else {
                 // return readOnlySnapshot ();
                 continue;
@@ -392,7 +377,7 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
     final public void clear () {
         while (true) {
             INode<K, V> r = RDCSS_READ_ROOT ();
-            if (!RDCSS_ROOT (r, r.gcasRead (this), INode.<K, V>newRootNode ())) {
+            if (!RDCSS_ROOT(r, r.gcasRead(this), newRootNode())) {
                 continue;
             }else{
                 return;
@@ -400,9 +385,12 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
         }
     }
 
-    // @inline
-    int computeHash (final K k) {
-        return hashingobj.hash (k);
+    int computeHash(final K k) {
+        return equiv.hash(k);
+    }
+
+    boolean equal(final K k1, final K k2) {
+        return equiv.equivalent(k1, k2);
     }
 
     final V lookup (final K k) {
@@ -418,21 +406,6 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
         }
     }
 
-    final V apply (final K k) {
-        int hc = computeHash (k);
-        Object res = lookuphc (k, hc);
-        if (res == null) {
-            throw new NoSuchElementException ();
-        } else {
-            return (V) res;
-        }
-    }
-
-//    final public Option<V> get (K k) {
-//        int hc = computeHash (k);
-//        return Option.makeOption ((V)lookuphc (k, hc));
-//    }
-
     @Override
     final public V get (final Object k) {
         return lookup((K)k);
@@ -665,7 +638,7 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
                 }
 
                 lastReturned = r;
-                if(r instanceof Map.Entry) {
+                if (r != null) {
                     final Map.Entry<K, V> rr = r;
                     return nextEntry(rr);
                 }
@@ -905,7 +878,7 @@ public class TrieMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K,
 
     private void readObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
         inputStream.defaultReadObject();
-        this.root = INode.newRootNode();
+        this.root = newRootNode();
 
         final boolean ro = inputStream.readBoolean();
         final int size = inputStream.readInt();