// 3) an l-node
final LNode<K, V> ln = (LNode<K, V>) m;
if (cond == null) {
- final Optional<V> optv = ln.get(k);
+ final Optional<V> optv = ln.get(ct.equiv(), k);
if (insertln(ln, k, v, ct)) {
return optv;
}
return null;
} else if (cond == ABSENT) {
- final Optional<V> t = ln.get(k);
+ final Optional<V> t = ln.get(ct.equiv(),k);
if (t.isPresent()) {
return t;
}
}
return null;
} else if (cond == PRESENT) {
- final Optional<V> t = ln.get(k);
+ final Optional<V> t = ln.get(ct.equiv(),k);
if (!t.isPresent()) {
return t;
}
}
return null;
} else {
- final Optional<V> t = ln.get(k);
+ final Optional<V> t = ln.get(ct.equiv(),k);
if (t.isPresent()) {
if (cond.equals(t.get())) {
if (insertln(ln, k, v, ct)) {
}
private boolean insertln(final LNode<K, V> ln, final K k, final V v, final TrieMap<K, V> ct) {
- return GCAS(ln, ln.addChild(k, v), ct);
+ return GCAS(ln, ln.addChild(ct.equiv(), k, v), ct);
}
/**
return cleanReadOnly((TNode<K, V>) m, lev, parent, ct, k, hc);
} else if (m instanceof LNode) {
// 5) an l-node
- return ((LNode<K, V>) m).get(k).orElse(null);
+ return ((LNode<K, V>) m).get(ct.equiv(), k).orElse(null);
} else {
throw new IllegalStateException("Unhandled node " + m);
}
return null;
} else if (m instanceof LNode) {
final LNode<K, V> ln = (LNode<K, V>) m;
- final Optional<V> optv = ln.get(k);
+ final Optional<V> optv = ln.get(ct.equiv(), k);
if (!optv.isPresent()) {
// Key was not found, hence no modification is needed
return Optional.empty();
}
- return GCAS(ln, ln.removeChild(k, hc, ct), ct) ? optv : null;
+ return GCAS(ln, ln.removeChild(ct.equiv(), k, hc), ct) ? optv : null;
} else {
throw new IllegalStateException("Unhandled node " + m);
}
this(ListMap.map(k1, v1, k2, v2));
}
- LNode<K, V> addChild(final K k, final V v) {
- return new LNode<>(listmap.add(k, v));
+ LNode<K, V> addChild(final Equivalence<? super K> equiv, final K k, final V v) {
+ return new LNode<>(listmap.add(equiv, k, v));
}
- MainNode<K, V> removeChild(final K k, final int hc, final TrieMap<K, V> ct) {
+ MainNode<K, V> removeChild(final Equivalence<? super K> equiv, final K k, final int hc) {
// 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 ListMap<K, V> map = listmap.remove(k);
+ final ListMap<K, V> map = listmap.remove(equiv, k);
final Optional<Entry<K, V>> maybeKv = map.maybeSingleton();
if (maybeKv.isPresent()) {
final Entry<K, V> kv = maybeKv.get();
return new LNode<>(map);
}
- Optional<V> get(final K k) {
- return listmap.get(k);
+ Optional<V> get(final Equivalence<? super K> equiv, final K k) {
+ return listmap.get(equiv, k);
}
@Override
return sz;
}
- Optional<V> get(final K key) {
- if (key.equals(k)) {
- return Optional.of(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 Optional.of(m.v);
+ ListMap<K, V> head = this;
+ do {
+ if (equiv.equivalent(head.k, key)) {
+ return Optional.of(head.v);
}
- }
+
+ 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;
}
// 30K seems to be enough to trigger the problem locally
for (int i = 3; i < 30000; ++i) {
- map = map.add(i, Boolean.TRUE);
+ map = map.add(Equivalence.equals(), i, Boolean.TRUE);
}
- final Optional<Boolean> ret = map.get(0);
+ final Optional<Boolean> ret = map.get(Equivalence.equals(), 0);
assertFalse(ret.isPresent());
}