From 6c8920a2138a8a445e7478f5277a2c690cbb0ed6 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Mon, 2 Jan 2017 04:29:09 +0100 Subject: [PATCH] BUG-7464: Refactor KVNode 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 --- .../triemap/{KVNode.java => EntryNode.java} | 17 +++++- .../yangtools/triemap/EntryUtil.java | 55 +++++++++++++++++++ .../opendaylight/yangtools/triemap/SNode.java | 35 +++++++++--- .../opendaylight/yangtools/triemap/TNode.java | 35 +++++++++--- .../yangtools/triemap/TrieMap.java | 4 +- ...ListMapTest.java => LNodeEntriesTest.java} | 2 +- 6 files changed, 124 insertions(+), 24 deletions(-) rename third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/{KVNode.java => EntryNode.java} (61%) create mode 100644 third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryUtil.java rename third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/{ListMapTest.java => LNodeEntriesTest.java} (97%) diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/KVNode.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryNode.java 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 ac260fa010..d50b7d4738 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/KVNode.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryNode.java @@ -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 { - Entry kvPair(); +/** + * Common marker interface for nodes which act as an immutable {@link Entry}. + * + * @author Robert Varga + * + * @param the type of key + * @param the type of value + */ +interface EntryNode extends Entry { + @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 index 0000000000..a73797eff3 --- /dev/null +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/EntryUtil.java @@ -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; + } +} diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/SNode.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/SNode.java index 0530b58b4d..395c477b00 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/SNode.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/SNode.java @@ -15,10 +15,7 @@ */ package org.opendaylight.yangtools.triemap; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.Map.Entry; - -final class SNode extends BasicNode implements KVNode { +final class SNode extends BasicNode implements EntryNode { final K k; final V v; final int hc; @@ -41,14 +38,34 @@ final class SNode extends BasicNode implements KVNode { return new SNode<>(k, v, hc); } - @Override - public Entry 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 diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TNode.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TNode.java index 27a925cc8e..45913d1b41 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TNode.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TNode.java @@ -15,10 +15,7 @@ */ package org.opendaylight.yangtools.triemap; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.Map.Entry; - -final class TNode extends MainNode implements KVNode { +final class TNode extends MainNode implements EntryNode { final K k; final V v; final int hc; @@ -41,11 +38,6 @@ final class TNode extends MainNode implements KVNode { return new SNode<>(k, v, hc); } - @Override - public Entry kvPair () { - return new SimpleImmutableEntry<>(k, v); - } - @Override int cachedSize(final TrieMap ct) { return 1; @@ -56,4 +48,29 @@ final class TNode extends MainNode implements KVNode { // (" " * 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 diff --git a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java index 0b2b898791..e421646ed0 100644 --- a/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java +++ b/third-party/triemap/src/main/java/org/opendaylight/yangtools/triemap/TrieMap.java @@ -443,7 +443,7 @@ public final class TrieMap extends AbstractMap implements Concurrent private final int[] stackpos = new int[7]; private int depth = -1; private Iterator> subiter = null; - private KVNode current = null; + private EntryNode current = null; private Entry lastReturned = null; TrieMapIterator (final int level, final TrieMap ct, final boolean mustInit) { @@ -476,7 +476,7 @@ public final class TrieMap extends AbstractMap implements Concurrent r = subiter.next (); checkSubiter (); } else { - r = current.kvPair (); + r = current; advance (); } diff --git a/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java b/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/LNodeEntriesTest.java 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 0786ce852e..96e64794f9 100644 --- a/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/ListMapTest.java +++ b/third-party/triemap/src/test/java/org/opendaylight/yangtools/triemap/LNodeEntriesTest.java @@ -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. */ -- 2.36.6