private boolean rec_insert(final K k, final V v, final int hc, final int lev, final INode<K, V> parent,
final Gen startgen, final TrieMap<K, V> ct) {
while (true) {
- final MainNode<K, V> m = GCAS_READ (ct); // use -Yinline!
+ final MainNode<K, V> m = GCAS_READ(ct); // use -Yinline!
if (m instanceof CNode) {
// 1) a multiway node
clean(parent, ct, lev - 5);
return false;
} else if (m instanceof LNode) {
- return insertln((LNode<K, V>) m, k, v, ct);
+ final LNode<K, V> ln = (LNode<K, V>) m;
+ final LNodeEntry<K, V> entry = ln.get(ct.equiv(), k);
+ return entry != null ? replaceln(ln, entry, v, ct) : insertln(ln, k, v, ct);
} else {
throw new IllegalStateException("Unhandled node " + m);
}
} else if (m instanceof LNode) {
// 3) an l-node
final LNode<K, V> ln = (LNode<K, V>) m;
+ final LNodeEntry<K, V> entry = ln.get(ct.equiv(), k);
+
if (cond == null) {
- final Optional<V> optv = ln.get(k);
- if (insertln(ln, k, v, ct)) {
- return optv;
+ if (entry != null) {
+ return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null;
}
- return null;
+
+ return insertln(ln, k, v, ct) ? Optional.empty() : null;
} else if (cond == ABSENT) {
- final Optional<V> t = ln.get(k);
- if (t.isPresent()) {
- return t;
+ if (entry != null) {
+ return Optional.of(entry.value());
}
- if (insertln(ln, k, v, ct)) {
- return Optional.empty();
- }
- return null;
+
+ return insertln(ln, k, v, ct) ? Optional.empty() : null;
} else if (cond == PRESENT) {
- final Optional<V> t = ln.get(k);
- if (!t.isPresent()) {
- return t;
- }
- if (insertln(ln, k, v, ct)) {
- return t;
+ if (entry == null) {
+ return Optional.empty();
}
- return null;
- } else {
- final Optional<V> t = ln.get(k);
- if (t.isPresent()) {
- if (cond.equals(t.get())) {
- if (insertln(ln, k, v, ct)) {
- // Difference from Scala: we choose to reuse the object returned from LNode,
- // as the identity of the value does not matter in this call graph.
- return t;
- }
- return null;
- }
+ return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null;
+ } else {
+ if (entry == null || !cond.equals(entry.value())) {
+ return Optional.empty();
}
- return Optional.empty();
+ return replaceln(ln, entry, v, ct) ? Optional.of(entry.value()) : null;
}
} else {
throw new IllegalStateException("Unhandled node " + m);
}
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.insertChild(k, v), ct);
+ }
+
+ private boolean replaceln(final LNode<K, V> ln, final LNodeEntry<K, V> entry, final V v, final TrieMap<K, V> ct) {
+ return GCAS(ln, ln.replaceChild(entry, 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);
+ final LNodeEntry<K, V> entry = ((LNode<K, V>) m).get(ct.equiv(), k);
+ return entry != null ? entry.value() : 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);
-
- if (!optv.isPresent()) {
+ final LNodeEntry<K, V> entry = ln.get(ct.equiv(), k);
+ if (entry == null) {
// Key was not found, hence no modification is needed
return Optional.empty();
}
- if (v != null && !v.equals(optv.get())) {
+ final V value = entry.value();
+ if (v != null && !v.equals(value)) {
// Value does not match
return Optional.empty();
}
- return GCAS(ln, ln.removeChild(k, hc, ct), ct) ? optv : null;
+ return GCAS(ln, ln.removeChild(entry, hc), ct) ? Optional.of(value) : null;
} else {
throw new IllegalStateException("Unhandled node " + m);
}