Since LNodeEntry already contains a key/value mapping, it is
advantageous to make it also implement Map.Entry, simply
because that allows us to skip temporary object instantiation
when iterating over entries.
This could be done via subclassing SimpleImmutableEntry, but
that forces us to implement Serializable, which is not what
we want.
Change-Id: I3b0a2384dfbb9c2ed14dd6c9d66dfe91e883f97a
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
if (cond == null) {
if (entry != null) {
if (cond == null) {
if (entry != null) {
- return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null;
+ return replaceln(ln, entry, v, ct) ? Optional.of(entry.getValue()) : null;
}
return insertln(ln, k, v, ct) ? Optional.empty() : null;
} else if (cond == ABSENT) {
if (entry != null) {
}
return insertln(ln, k, v, ct) ? Optional.empty() : null;
} else if (cond == ABSENT) {
if (entry != null) {
- return Optional.of(entry.value());
+ return Optional.of(entry.getValue());
}
return insertln(ln, k, v, ct) ? Optional.empty() : null;
}
return insertln(ln, k, v, ct) ? Optional.empty() : null;
return Optional.empty();
}
return Optional.empty();
}
- return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null;
+ return replaceln(ln, entry, v, ct) ? Optional.of(entry.getValue()) : null;
- if (entry == null || !cond.equals(entry.value())) {
+ if (entry == null || !cond.equals(entry.getValue())) {
return Optional.empty();
}
return Optional.empty();
}
- return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null;
+ return replaceln(ln, entry, v, ct) ? Optional.of(entry.getValue()) : null;
}
} else {
throw new IllegalStateException("Unhandled node " + m);
}
} else {
throw new IllegalStateException("Unhandled node " + m);
} else if (m instanceof LNode) {
// 5) an l-node
final LNodeEntry<K, V> entry = ((LNode<K, V>) m).get(ct.equiv(), k);
} else if (m instanceof LNode) {
// 5) an l-node
final LNodeEntry<K, V> entry = ((LNode<K, V>) m).get(ct.equiv(), k);
- return entry != null ? entry.value() : null;
+ return entry != null ? entry.getValue() : null;
} else {
throw new IllegalStateException("Unhandled node " + m);
}
} else {
throw new IllegalStateException("Unhandled node " + m);
}
return Optional.empty();
}
return Optional.empty();
}
- final V value = entry.value();
+ final V value = entry.getValue();
if (cond != null && !cond.equals(value)) {
// Value does not match
return Optional.empty();
if (cond != null && !cond.equals(value)) {
// Value does not match
return Optional.empty();
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Iterator;
import java.util.Map.Entry;
-import java.util.Optional;
final class LNode<K, V> extends MainNode<K, V> {
private final LNodeEntries<K, V> listmap;
final class LNode<K, V> extends MainNode<K, V> {
private final LNodeEntries<K, V> listmap;
// We only ever create ListMaps with two or more entries, and remove them as soon as they reach one element
// (below), so we cannot observe a null return here.
final LNodeEntries<K, V> map = listmap.remove(entry);
// We only ever create ListMaps with two or more entries, and remove them as soon as they reach one element
// (below), so we cannot observe a null return here.
final LNodeEntries<K, V> map = listmap.remove(entry);
- final Optional<Entry<K, V>> maybeKv = map.maybeSingleton();
- if (maybeKv.isPresent()) {
- final Entry<K, V> kv = maybeKv.get();
// create it tombed so that it gets compressed on subsequent accesses
// create it tombed so that it gets compressed on subsequent accesses
- return new TNode<>(kv.getKey(), kv.getValue(), hc);
+ return new TNode<>(map.getKey(), map.getValue(), hc);
}
return new LNode<>(map);
}
return new LNode<>(map);
Iterator<Entry<K, V>> iterator() {
return listmap.iterator();
}
Iterator<Entry<K, V>> iterator() {
return listmap.iterator();
}
}
\ No newline at end of file
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.triemap;
*/
package org.opendaylight.yangtools.triemap;
-import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
-import java.util.Optional;
/**
* Similar to Scala's ListMap. Stores a linked set of entries, guaranteed to contain unique entry keys.
/**
* Similar to Scala's ListMap. Stores a linked set of entries, guaranteed to contain unique entry keys.
* @param <V> the type of values
*/
final class LNodeEntries<K, V> extends LNodeEntry<K, V> {
* @param <V> the type of values
*/
final class LNodeEntries<K, V> extends LNodeEntry<K, V> {
- // Modified during remove0 only
+ // Modified during remove only
private LNodeEntries<K, V> next;
private LNodeEntries(final K k, final V v) {
private LNodeEntries<K, V> next;
private LNodeEntries(final K k, final V v) {
return new LNodeEntries<>(k1, v1, new LNodeEntries<>(k2, v2));
}
return new LNodeEntries<>(k1, v1, new LNodeEntries<>(k2, v2));
}
- Optional<Entry<K, V>> maybeSingleton() {
- return next != null ? Optional.empty() : Optional.of(new SimpleImmutableEntry<>(key(), value()));
+ boolean isSingle() {
+ return next == null;
LNodeEntry<K, V> findEntry(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.
LNodeEntry<K, V> findEntry(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.
- LNodeEntries<K, V> head = this;
+ LNodeEntries<K, V> entry = this;
- if (equiv.equivalent(head.key(), key)) {
- return head;
+ if (equiv.equivalent(entry.getKey(), key)) {
+ return entry;
- head = head.next;
- } while (head != null);
+ entry = entry.next;
+ } while (entry != null);
}
LNodeEntries<K, V> replace(final LNodeEntry<K, V> entry, final V v) {
}
LNodeEntries<K, V> replace(final LNodeEntry<K, V> entry, final V v) {
- return new LNodeEntries<>(entry.key(), v, remove(entry));
+ return new LNodeEntries<>(entry.getKey(), v, remove(entry));
}
LNodeEntries<K, V> remove(final LNodeEntry<K, V> entry) {
}
LNodeEntries<K, V> remove(final LNodeEntry<K, V> entry) {
- final LNodeEntries<K, V> ret = new LNodeEntries<>(key(), value());
+ final LNodeEntries<K, V> ret = new LNodeEntries<>(getKey(), getValue());
LNodeEntries<K, V> last = ret;
LNodeEntries<K, V> cur = next;
while (cur != null) {
LNodeEntries<K, V> last = ret;
LNodeEntries<K, V> cur = next;
while (cur != null) {
- if (entry.equals(cur)) {
+ // We cannot use equals() here, as it is wired to key/value equality,
+ // which we really do not want.
+ if (entry == cur) {
last.next = cur.next;
return ret;
}
last.next = cur.next;
return ret;
}
- last.next = new LNodeEntries<>(cur.key(), cur.value());
+ last.next = new LNodeEntries<>(cur.getKey(), cur.getValue());
last = last.next;
cur = cur.next;
}
last = last.next;
cur = cur.next;
}
- throw new IllegalStateException("Entry " + entry + " not found in entries " + this);
+ throw new IllegalStateException(String.format("Entry %s not found", entry));
}
Iterator<Entry<K, V>> iterator() {
}
Iterator<Entry<K, V>> iterator() {
throw new NoSuchElementException();
}
throw new NoSuchElementException();
}
- final Entry<K, V> res = new SimpleImmutableEntry<>(n.key(), n.value());
+ final Entry<K, V> res = n;
n = n.next;
return res;
}
n = n.next;
return res;
}
*/
package org.opendaylight.yangtools.triemap;
*/
package org.opendaylight.yangtools.triemap;
+import java.util.Map.Entry;
+
- * A single entry in {@link LNodeEntries}.
+ * A single entry in {@link LNodeEntries}, implements {@link Entry} in order to prevent instantiation of objects for
+ * iteration.
*
* @author Robert Varga
*
* @param <K> the type of key
* @param <V> the type of value
*/
*
* @author Robert Varga
*
* @param <K> the type of key
* @param <V> the type of value
*/
-abstract class LNodeEntry<K, V> {
- private final V value;
+abstract class LNodeEntry<K, V> implements Entry<K, V> {
LNodeEntry(final K key, final V value) {
LNodeEntry(final K key, final V value) {
+ @Override
+ public final K getKey() {
+ @Override
+ public final V getValue() {
+ @Override
+ public final V setValue(final V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public final int hashCode() {
+ return EntryUtil.hash(key, value);
+ }
+
+ @Override
+ public final boolean equals(final Object o) {
+ return EntryUtil.equal(o, key, value);
+ }
+
+ @Override
+ public final String toString() {
+ return EntryUtil.string(key, value);
+ }