BUG-7464: Make ListMap obey TrieMap equivalence
[yangtools.git] / third-party / triemap / src / main / java / org / opendaylight / yangtools / triemap / ListMap.java
index 9978b5f627168ae57159e4c5789bbe01f6968587..b2f1c10af5f02b41934c609fbfe3c286416d6690 100644 (file)
@@ -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
@@ -48,6 +49,10 @@ final class ListMap<K, V> {
         return new ListMap<>(k1, v1, new ListMap<>(k2, v2));
     }
 
+    Optional<Entry<K, V>> maybeSingleton() {
+        return next != null ? Optional.empty() : Optional.of(new SimpleImmutableEntry<>(k, v));
+    }
+
     int size() {
         int sz = 1;
         for (ListMap<?, ?> wlk = next; wlk != null; wlk = wlk.next) {
@@ -56,44 +61,41 @@ final class ListMap<K, V> {
         return sz;
     }
 
-    Option<V> get(final K key) {
-        if (key.equals(k)) {
-            return Option.makeOption(v);
-        }
-
+    Optional<V> get(final Equivalence<? super K> equiv, final K key) {
         // We do not perform recursion on purpose here, so we do not run out of stack if the key hashing fails.
-        for (ListMap<K, V> m = next; m != null; m = m.next) {
-            if (key.equals(m.k)) {
-                return Option.makeOption(m.v);
+        ListMap<K, V> head = this;
+        do {
+            if (equiv.equivalent(head.k, key)) {
+                return Optional.of(head.v);
             }
-        }
 
-        return Option.makeOption();
+            head = head.next;
+        } while (head != null);
+
+        return Optional.empty();
     }
 
-    ListMap<K,V> add(final K key, final V value) {
-        return new ListMap<>(key, value, remove(key));
+    ListMap<K,V> add(final Equivalence<? super K> equiv, final K key, final V value) {
+        return new ListMap<>(key, value, remove(equiv, key));
     }
 
-    ListMap<K, V> remove(final K key) {
-         if (!contains(key)) {
+    ListMap<K, V> remove(final Equivalence<? super K> equiv, final K key) {
+         if (!contains(equiv, key)) {
             return this;
         }
 
         return remove0(key);
     }
 
-    private boolean contains(final K key) {
-        if (key.equals(k)) {
-            return true;
-        }
-
+    private boolean contains(final Equivalence<? super K> equiv, final K key) {
         // We do not perform recursion on purpose here, so we do not run out of stack if the key hashing fails.
-        for (ListMap<K, V> m = next; m != null; m = m.next) {
-            if (key.equals(m.k)) {
+        ListMap<K, V> head = this;
+        do {
+            if (equiv.equivalent(head.k, key)) {
                 return true;
             }
-        }
+            head = head.next;
+        } while (head != null);
 
         return false;
     }