com.ajjpj.afoundation.collection.immutable.ABTreeMap Maven / Gradle / Ivy
The newest version!
package com.ajjpj.afoundation.collection.immutable;
import com.ajjpj.afoundation.collection.AEquality;
import com.ajjpj.afoundation.function.AFunction1;
import java.util.*;
/**
* An immutable BTree implementation
*
* @author arno
*/
public abstract class ABTreeMap extends AbstractAMap {
public final ABTreeSpec spec;
transient private Integer cachedHashcode = null; // intentionally not volatile: This class is immutable, so recalculating per thread works
@SuppressWarnings ("unchecked")
public static ABTreeMap empty (ABTreeSpec spec) {
return new LeafNode (spec, new Object[0], new Object[0]);
}
ABTreeMap (ABTreeSpec spec) {
this.spec = spec;
}
public abstract AOption get (K key);
// public Iterable keys ();
// public Iterable values ();
// public Iterable keys (K keyMin, K keyMax);
// public Iterable values (K keyMin, K keyMax);
@SuppressWarnings ("unchecked")
public ABTreeMap updated (K key, V value) {
final UpdateResult result = _updated (key, value);
if (result.optRight == null) {
return result.left;
}
// This is the only place where the tree depth can grow.
// The 'minimum number of children' constraint does not apply to root nodes.
return new IndexNode (spec, new Object[] {result.separator}, new ABTreeMap[] {result.left, result.optRight});
}
@SuppressWarnings ("unchecked")
public ABTreeMap removed (K key) {
final RemoveResult removeResult = _removed (key, null);
if (removeResult.underflowed &&
removeResult.newNode instanceof IndexNode &&
((IndexNode) removeResult.newNode).children.length == 1) {
return ((IndexNode) removeResult.newNode).children[0];
}
return _removed (key, null).newNode;
}
abstract UpdateResult _updated (Object key, Object value);
abstract RemoveResult _removed (Object key, Object leftSeparator);
abstract UpdateResult merge (ABTreeMap rightNeighbour, Object separator);
@Override public ASet keys () {
return ABTreeSet.create (this);
}
@Override public AMap clear () {
return empty (spec);
}
@Override public AEquality keyEquality () {
return new AEquality.ComparatorBased (spec.comparator);
}
@Override public Iterator> iterator () {
return new BTreeIterator<> (this);
}
private static class BTreeIterator implements Iterator>, AMapEntry {
private final Deque