BUG-7464: Refactor KVNode 23/49923/12
authorRobert Varga <rovarga@cisco.com>
Mon, 2 Jan 2017 03:29:09 +0000 (04:29 +0100)
committerRobert Varga <rovarga@cisco.com>
Tue, 10 Jan 2017 19:12:11 +0000 (20:12 +0100)
KVNode is not really useful, as it acts like a factory method
for turning SNode/TNode into an Map.Entry.

We do not compare those nodes based on identity, hence we can
safely make them implement immutable version of Entry interface.

In order to keep some safety, we retain the interface, renamed
to EntryNode, extending Map.Entry and providing a default
setValue() implementation.

This has the added benefit of not needing object allocation
during iteration.

Change-Id: I27e3049739f4eb97ee76e8462c9ddde3c4b5b17a
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryNode.java [moved from third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/KVNode.java with 61% similarity]
third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryUtil.java [new file with mode: 0644]
third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/SNode.java
third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TNode.java
third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java
third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/LNodeEntriesTest.java [moved from third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java with 97% similarity]

similarity index 61%
rename from third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/KVNode.java
rename to third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryNode.java
index ac260fa01037b6131f4b07b36e9cf842027eada4..d50b7d473842c37da4290f7d296b922ed8f3756c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2016 Pantheon Technologies, s.r.o. and others.
+ * (C) Copyright 2017 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.
@@ -17,6 +17,17 @@ package org.opendaylight.yangtools.triemap;
 
 import java.util.Map.Entry;
 
-interface KVNode<K, V> {
-    Entry<K, V> kvPair();
+/**
+ * Common marker interface for nodes which act as an immutable {@link Entry}.
+ *
+ * @author Robert Varga
+ *
+ * @param <K> the type of key
+ * @param <V> the type of value
+ */
+interface EntryNode<K, V> extends Entry<K, V> {
+    @Override
+    default public V setValue(final V value) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryUtil.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryUtil.java
new file mode 100644 (file)
index 0000000..a73797e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2017 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;
+
+import java.util.Map.Entry;
+
+/**
+ * Utility methods for implementing {@link Entry} contract.
+ *
+ * @author Robert Varga
+ */
+final class EntryUtil {
+    private EntryUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Utility implementing {@link Entry#equals(Object)}.
+     */
+    static boolean equal(final Object o, final Object key, final Object value) {
+        if (!(o instanceof Entry)) {
+            return false;
+        }
+
+        final Entry<?,?> e = (Entry<?,?>)o;
+        return key.equals(e.getKey()) && value.equals(e.getValue());
+    }
+
+    /**
+     * Utility implementing {@link Entry#hashCode()}.
+     */
+    static int hash(final Object key, final Object value) {
+        return key.hashCode() ^ value.hashCode();
+    }
+
+    /**
+     * Utility implementing {@link Entry#toString()}.
+     */
+    static String string(final Object key, final Object value) {
+        return key + "=" + value;
+    }
+}
index 0530b58b4d106409c866b2270e2405c8573e9a43..395c477b00ee90f5869bda1a0bb8e616eb8aebee 100644 (file)
  */
 package org.opendaylight.yangtools.triemap;
 
-import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Map.Entry;
-
-final class SNode<K, V> extends BasicNode implements KVNode<K, V> {
+final class SNode<K, V> extends BasicNode implements EntryNode<K, V> {
     final K k;
     final V v;
     final int hc;
@@ -41,14 +38,34 @@ final class SNode<K, V> extends BasicNode implements KVNode<K, V> {
         return new SNode<>(k, v, hc);
     }
 
-    @Override
-    public Entry<K, V> kvPair() {
-        return new SimpleImmutableEntry<>(k, v);
-    }
-
     @Override
     String string(final int lev) {
         // ("  " * lev) + "SNode(%s, %s, %x)".format(k, v, hc);
         return "SNode";
     }
+
+    @Override
+    public K getKey() {
+        return k;
+    }
+
+    @Override
+    public V getValue() {
+        return v;
+    }
+
+    @Override
+    public int hashCode() {
+        return EntryUtil.hash(k, v);
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        return EntryUtil.equal(o, k, v);
+    }
+
+    @Override
+    public String toString() {
+        return EntryUtil.string(k, v);
+    }
 }
\ No newline at end of file
index 27a925cc8ef094214b36c6fd6ce843e94c303d77..45913d1b416fdcaf3966c3a3404131dd46b865da 100644 (file)
  */
 package org.opendaylight.yangtools.triemap;
 
-import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Map.Entry;
-
-final class TNode<K, V> extends MainNode<K, V> implements KVNode<K, V> {
+final class TNode<K, V> extends MainNode<K, V> implements EntryNode<K, V> {
     final K k;
     final V v;
     final int hc;
@@ -41,11 +38,6 @@ final class TNode<K, V> extends MainNode<K, V> implements KVNode<K, V> {
         return new SNode<>(k, v, hc);
     }
 
-    @Override
-    public Entry<K, V> kvPair () {
-        return new SimpleImmutableEntry<>(k, v);
-    }
-
     @Override
     int cachedSize(final TrieMap<K, V> ct) {
         return 1;
@@ -56,4 +48,29 @@ final class TNode<K, V> extends MainNode<K, V> implements KVNode<K, V> {
         // ("  " * lev) + "TNode(%s, %s, %x, !)".format(k, v, hc);
         return "TNode";
     }
+
+    @Override
+    public K getKey() {
+        return k;
+    }
+
+    @Override
+    public V getValue() {
+        return v;
+    }
+
+    @Override
+    public int hashCode() {
+        return EntryUtil.hash(k, v);
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        return EntryUtil.equal(o, k, v);
+    }
+
+    @Override
+    public String toString() {
+        return EntryUtil.string(k, v);
+    }
 }
\ No newline at end of file
index 0b2b8987919f9bba75ee12e596b83334a39c68b8..e421646ed0cb0ecbfdf50d6a55535fd145236bae 100644 (file)
@@ -443,7 +443,7 @@ public final class TrieMap<K, V> extends AbstractMap<K, V> implements Concurrent
         private final int[] stackpos = new int[7];
         private int depth = -1;
         private Iterator<Entry<K, V>> subiter = null;
-        private KVNode<K, V> current = null;
+        private EntryNode<K, V> current = null;
         private Entry<K, V> lastReturned = null;
 
         TrieMapIterator (final int level, final TrieMap<K, V> ct, final boolean mustInit) {
@@ -476,7 +476,7 @@ public final class TrieMap<K, V> extends AbstractMap<K, V> implements Concurrent
                 r = subiter.next ();
                 checkSubiter ();
             } else {
-                r = current.kvPair ();
+                r = current;
                 advance ();
             }
 
similarity index 97%
rename from third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java
rename to third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/LNodeEntriesTest.java
index 0786ce852e676cfdbb8b18ff74d2fed5af079c36..96e64794f9e172fdf544920571777aa5f34b05c4 100644 (file)
@@ -19,7 +19,7 @@ import static org.junit.Assert.assertNull;
 
 import org.junit.Test;
 
-public class ListMapTest {
+public class LNodeEntriesTest {
     /**
      * Test if Listmap.get() does not cause stack overflow.
      */