3097 lines
104 KiB
Plaintext
3097 lines
104 KiB
Plaintext
package speiger.src.collections.PACKAGE.maps.impl.tree;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Map;
|
|
#if TYPE_OBJECT
|
|
import java.util.Comparator;
|
|
#endif
|
|
import java.util.Objects;
|
|
import java.util.NoSuchElementException;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.BiFunction;
|
|
import java.util.function.Predicate;
|
|
#if !TYPE_OBJECT && JDK_TYPE
|
|
import java.util.function.PREDICATE;
|
|
#endif
|
|
#if !SAME_TYPE && JDK_VALUE && !VALUE_OBJECT
|
|
import java.util.function.VALUE_PREDICATE;
|
|
#endif
|
|
|
|
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
|
|
#if !TYPE_OBJECT
|
|
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
|
import speiger.src.collections.PACKAGE.functions.CONSUMER;
|
|
import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER;
|
|
#endif
|
|
import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER;
|
|
#if !TYPE_OBJECT && !VALUE_OBJECT
|
|
import speiger.src.collections.ints.functions.consumer.IntObjectConsumer;
|
|
#endif
|
|
#if !SAME_TYPE && !TYPE_INT
|
|
import speiger.src.collections.ints.functions.consumer.VALUE_BI_FROM_INT_CONSUMER;
|
|
#endif
|
|
#if !VALUE_BOOLEAN || !JDK_TYPE
|
|
import speiger.src.collections.PACKAGE.functions.function.FUNCTION;
|
|
#endif
|
|
#if !TYPE_INT || !SAME_TYPE
|
|
import speiger.src.collections.PACKAGE.functions.consumer.BI_CONSUMER;
|
|
#endif
|
|
#if !TYPE_OBJECT && !VALUE_BOOLEAN && !JDK_TYPE
|
|
import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
|
|
#endif
|
|
import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR;
|
|
#if !SAME_TYPE
|
|
import speiger.src.collections.PACKAGE.functions.function.SINGLE_UNARY_OPERATOR;
|
|
#endif
|
|
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
|
|
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
|
|
import speiger.src.collections.PACKAGE.maps.interfaces.NAVIGABLE_MAP;
|
|
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
|
|
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
|
|
#if TYPE_OBJECT
|
|
import speiger.src.collections.PACKAGE.sets.SET;
|
|
#endif
|
|
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ABSTRACT_COLLECTION;
|
|
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_COLLECTION;
|
|
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_ITERATOR;
|
|
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_SUPPLIER;
|
|
#if !SAME_TYPE
|
|
import speiger.src.collections.VALUE_PACKAGE.collections.VALUE_BI_ITERATOR;
|
|
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_UNARY_OPERATOR;
|
|
#endif
|
|
#if !VALUE_OBJECT && !SAME_TYPE
|
|
import speiger.src.collections.VALUE_PACKAGE.functions.VALUE_CONSUMER;
|
|
#endif
|
|
#if !TYPE_OBJECT && !VALUE_OBJECT || !VALUE_OBJECT
|
|
import speiger.src.collections.objects.functions.consumer.ObjectObjectConsumer;
|
|
#endif
|
|
#if !SAME_TYPE
|
|
#if !TYPE_OBJECT
|
|
import speiger.src.collections.objects.functions.consumer.VALUE_BI_FROM_OBJECT_CONSUMER;
|
|
|
|
#endif
|
|
#if !JDK_VALUE
|
|
import speiger.src.collections.VALUE_PACKAGE.functions.function.VALUE_PREDICATE;
|
|
#endif
|
|
#endif
|
|
#if !TYPE_OBJECT && !VALUE_OBJECT
|
|
import speiger.src.collections.objects.collections.ObjectBidirectionalIterator;
|
|
#endif
|
|
#if !VALUE_OBJECT
|
|
import speiger.src.collections.objects.collections.ObjectIterator;
|
|
#endif
|
|
#if !TYPE_OBJECT
|
|
#if !VALUE_OBJECT
|
|
import speiger.src.collections.objects.functions.function.ObjectObjectUnaryOperator;
|
|
|
|
#endif
|
|
import speiger.src.collections.objects.sets.AbstractObjectSet;
|
|
import speiger.src.collections.objects.sets.ObjectSet;
|
|
#endif
|
|
|
|
/**
|
|
* A Simple Type Specific RB TreeMap implementation that reduces boxing/unboxing.
|
|
* It is using a bit more memory then <a href="https://github.com/vigna/fastutil">FastUtil</a>,
|
|
* but it saves a lot of Performance on the Optimized removal and iteration logic.
|
|
* Which makes the implementation actually useable and does not get outperformed by Javas default implementation.
|
|
* @Type(T)
|
|
* @ValueType(V)
|
|
*/
|
|
public class RB_TREE_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE
|
|
{
|
|
/** The center of the Tree */
|
|
protected transient Node KEY_VALUE_GENERIC_TYPE tree;
|
|
/** The Lowest possible Node */
|
|
protected transient Node KEY_VALUE_GENERIC_TYPE first;
|
|
/** The Highest possible Node */
|
|
protected transient Node KEY_VALUE_GENERIC_TYPE last;
|
|
/** The amount of elements stored in the Map */
|
|
protected int size = 0;
|
|
/** The Sorter of the Tree */
|
|
protected transient COMPARATOR KEY_GENERIC_TYPE comparator;
|
|
|
|
#if !TYPE_OBJECT
|
|
/** the default return value for max searches */
|
|
protected KEY_TYPE defaultMaxNotFound = CLASS_TYPE.MIN_VALUE;
|
|
/** the default return value for min searches */
|
|
protected KEY_TYPE defaultMinNotFound = CLASS_TYPE.MAX_VALUE;
|
|
#endif
|
|
|
|
/** KeySet Cache */
|
|
protected NAVIGABLE_SET KEY_GENERIC_TYPE keySet;
|
|
/** Values Cache */
|
|
protected VALUE_COLLECTION VALUE_GENERIC_TYPE values;
|
|
/** EntrySet Cache */
|
|
protected ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet;
|
|
|
|
/**
|
|
* Default Constructor
|
|
*/
|
|
public RB_TREE_MAP() {
|
|
}
|
|
|
|
/**
|
|
* Constructor that allows to define the sorter
|
|
* @param comp the function that decides how the tree is sorted, can be null
|
|
*/
|
|
public RB_TREE_MAP(COMPARATOR KEY_GENERIC_TYPE comp) {
|
|
comparator = comp;
|
|
}
|
|
|
|
#if !TYPE_OBJECT || !VALUE_OBJECT
|
|
/**
|
|
* Helper constructor that allow to create a map from boxed values (it will unbox them)
|
|
* @param keys the keys that should be put into the map
|
|
* @param values the values that should be put into the map.
|
|
* @throws IllegalStateException if the keys and values do not match in lenght
|
|
*/
|
|
public RB_TREE_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values) {
|
|
this(keys, values, null);
|
|
}
|
|
|
|
/**
|
|
* Helper constructor that has a custom sorter and allow to create a map from boxed values (it will unbox them)
|
|
* @param keys the keys that should be put into the map
|
|
* @param values the values that should be put into the map.
|
|
* @param comp the function that decides how the tree is sorted, can be null
|
|
* @throws IllegalStateException if the keys and values do not match in lenght
|
|
*/
|
|
public RB_TREE_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, COMPARATOR KEY_GENERIC_TYPE comp) {
|
|
comparator = comp;
|
|
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
|
|
for(int i = 0,m=keys.length;i<m;i++) put(OBJ_TO_KEY(keys[i]), OBJ_TO_VALUE(values[i]));
|
|
}
|
|
|
|
#endif
|
|
/**
|
|
* Helper constructor that allow to create a map from unboxed values
|
|
* @param keys the keys that should be put into the map
|
|
* @param values the values that should be put into the map.
|
|
* @throws IllegalStateException if the keys and values do not match in lenght
|
|
*/
|
|
public RB_TREE_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values) {
|
|
this(keys, values, null);
|
|
}
|
|
|
|
/**
|
|
* Helper constructor that has a custom sorter and allow to create a map from unboxed values
|
|
* @param keys the keys that should be put into the map
|
|
* @param values the values that should be put into the map.
|
|
* @param comp the function that decides how the tree is sorted, can be null
|
|
* @throws IllegalStateException if the keys and values do not match in lenght
|
|
*/
|
|
public RB_TREE_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, COMPARATOR KEY_GENERIC_TYPE comp) {
|
|
comparator = comp;
|
|
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
|
|
for(int i = 0,m=keys.length;i<m;i++) put(keys[i], values[i]);
|
|
}
|
|
|
|
/**
|
|
* A Helper constructor that allows to create a Map with exactly the same values as the provided map.
|
|
* @param map the values that should be present in the map
|
|
*/
|
|
public RB_TREE_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map) {
|
|
this(map, null);
|
|
}
|
|
|
|
/**
|
|
* A Helper constructor that has a custom sorter and allows to create a Map with exactly the same values as the provided map.
|
|
* @param map the values that should be present in the map
|
|
* @param comp the function that decides how the tree is sorted, can be null
|
|
*/
|
|
public RB_TREE_MAP(Map<? extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, COMPARATOR KEY_GENERIC_TYPE comp) {
|
|
comparator = comp;
|
|
putAll(map);
|
|
}
|
|
|
|
/**
|
|
* A Type Specific Helper function that allows to create a new Map with exactly the same values as the provided map.
|
|
* @param map the values that should be present in the map
|
|
*/
|
|
public RB_TREE_MAP(MAP KEY_VALUE_GENERIC_TYPE map) {
|
|
this(map, null);
|
|
}
|
|
|
|
/**
|
|
* A Type Specific Helper function that has a custom sorter and allows to create a new Map with exactly the same values as the provided map.
|
|
* @param map the values that should be present in the map
|
|
* @param comp the function that decides how the tree is sorted, can be null
|
|
*/
|
|
public RB_TREE_MAP(MAP KEY_VALUE_GENERIC_TYPE map, COMPARATOR KEY_GENERIC_TYPE comp) {
|
|
comparator = comp;
|
|
putAll(map);
|
|
}
|
|
|
|
#if TYPE_OBJECT
|
|
/** only used for primitives
|
|
* @return null
|
|
*/
|
|
public KEY_TYPE getDefaultMaxValue() { return null; }
|
|
/** only used for primitives
|
|
* @return null
|
|
*/
|
|
public KEY_TYPE getDefaultMinValue() { return null; }
|
|
|
|
#else
|
|
@Override
|
|
public void setDefaultMaxValue(KEY_TYPE value) { defaultMaxNotFound = value; }
|
|
@Override
|
|
public KEY_TYPE getDefaultMaxValue() { return defaultMaxNotFound; }
|
|
@Override
|
|
public void setDefaultMinValue(KEY_TYPE value) { defaultMinNotFound = value; }
|
|
@Override
|
|
public KEY_TYPE getDefaultMinValue() { return defaultMinNotFound; }
|
|
|
|
#endif
|
|
|
|
@Override
|
|
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
if(tree == null) {
|
|
tree = first = last = new NodeKV_BRACES(key, value, null);
|
|
size++;
|
|
return getDefaultReturnValue();
|
|
}
|
|
int compare = 0;
|
|
Node KEY_VALUE_GENERIC_TYPE parent = tree;
|
|
while(true) {
|
|
if((compare = compare(key, parent.key)) == 0) return parent.setValue(value);
|
|
if(compare < 0) {
|
|
if(parent.left == null) break;
|
|
parent = parent.left;
|
|
}
|
|
else if(compare > 0) {
|
|
if(parent.right == null) break;
|
|
parent = parent.right;
|
|
}
|
|
}
|
|
Node KEY_VALUE_GENERIC_TYPE adding = new NodeKV_BRACES(key, value, parent);
|
|
if(compare < 0) {
|
|
parent.left = adding;
|
|
if(parent == first) first = adding;
|
|
}
|
|
else {
|
|
parent.right = adding;
|
|
if(parent == last) last = adding;
|
|
}
|
|
fixAfterInsertion(adding);
|
|
size++;
|
|
return getDefaultReturnValue();
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
if(tree == null) {
|
|
tree = first = last = new NodeKV_BRACES(key, value, null);
|
|
size++;
|
|
return getDefaultReturnValue();
|
|
}
|
|
int compare = 0;
|
|
Node KEY_VALUE_GENERIC_TYPE parent = tree;
|
|
while(true) {
|
|
if((compare = compare(key, parent.key)) == 0) {
|
|
if(VALUE_EQUALS(parent.value, getDefaultReturnValue())) return parent.setValue(value);
|
|
return parent.value;
|
|
}
|
|
if(compare < 0) {
|
|
if(parent.left == null) break;
|
|
parent = parent.left;
|
|
}
|
|
else if(compare > 0) {
|
|
if(parent.right == null) break;
|
|
parent = parent.right;
|
|
}
|
|
}
|
|
Node KEY_VALUE_GENERIC_TYPE adding = new NodeKV_BRACES(key, value, parent);
|
|
if(compare < 0) {
|
|
parent.left = adding;
|
|
if(parent == first) first = adding;
|
|
}
|
|
else {
|
|
parent.right = adding;
|
|
if(parent == last) last = adding;
|
|
}
|
|
fixAfterInsertion(adding);
|
|
size++;
|
|
return getDefaultReturnValue();
|
|
}
|
|
|
|
#if VALUE_PRIMITIVES
|
|
@Override
|
|
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
if(tree == null) {
|
|
tree = first = last = new NodeKV_BRACES(key, value, null);
|
|
size++;
|
|
return getDefaultReturnValue();
|
|
}
|
|
int compare = 0;
|
|
Node KEY_VALUE_GENERIC_TYPE parent = tree;
|
|
while(true) {
|
|
if((compare = compare(key, parent.key)) == 0) return parent.addTo(value);
|
|
if(compare < 0) {
|
|
if(parent.left == null) break;
|
|
parent = parent.left;
|
|
}
|
|
else if(compare > 0) {
|
|
if(parent.right == null) break;
|
|
parent = parent.right;
|
|
}
|
|
}
|
|
Node KEY_VALUE_GENERIC_TYPE adding = new NodeKV_BRACES(key, value, parent);
|
|
if(compare < 0) {
|
|
parent.left = adding;
|
|
if(parent == first) first = adding;
|
|
}
|
|
else {
|
|
parent.right = adding;
|
|
if(parent == last) last = adding;
|
|
}
|
|
fixAfterInsertion(adding);
|
|
size++;
|
|
return getDefaultReturnValue();
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE subFrom(KEY_TYPE key, VALUE_TYPE value) {
|
|
if(tree == null) return getDefaultReturnValue();
|
|
int compare = 0;
|
|
Node KEY_VALUE_GENERIC_TYPE parent = tree;
|
|
while(true) {
|
|
if((compare = compare(key, parent.key)) == 0)
|
|
{
|
|
VALUE_TYPE oldValue = parent.subFrom(value);
|
|
if(value < 0 ? (parent.value >= getDefaultReturnValue()) : (parent.value <= getDefaultReturnValue())) removeNode(parent);
|
|
return oldValue;
|
|
}
|
|
if(compare < 0) {
|
|
if(parent.left == null) break;
|
|
parent = parent.left;
|
|
}
|
|
else if(compare > 0) {
|
|
if(parent.right == null) break;
|
|
parent = parent.right;
|
|
}
|
|
}
|
|
return getDefaultReturnValue();
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; }
|
|
|
|
#if TYPE_OBJECT
|
|
@Override
|
|
public boolean containsKey(Object key) {
|
|
return findNode((KEY_TYPE)key) != null;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public boolean containsKey(KEY_TYPE key) {
|
|
return findNode(key) != null;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public VALUE_TYPE GET_VALUE(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode(key);
|
|
return node == null ? getDefaultReturnValue() : node.value;
|
|
}
|
|
|
|
#if TYPE_OBJECT && VALUE_OBJECT
|
|
@Override
|
|
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode((CLASS_TYPE)key);
|
|
return node == null ? defaultValue : node.value;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode(key);
|
|
return node == null ? defaultValue : node.value;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public KEY_TYPE FIRST_ENTRY_KEY() {
|
|
if(tree == null) throw new NoSuchElementException();
|
|
return first.key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
|
|
if(tree == null) return getDefaultMinValue();
|
|
KEY_TYPE result = first.key;
|
|
removeNode(first);
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE LAST_ENTRY_KEY() {
|
|
if(tree == null) throw new NoSuchElementException();
|
|
return last.key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE POLL_LAST_ENTRY_KEY() {
|
|
if(tree == null) return getDefaultMaxValue();
|
|
KEY_TYPE result = last.key;
|
|
removeNode(last);
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
|
|
if(tree == null) return null;
|
|
return first.export();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
|
|
if(tree == null) return null;
|
|
return last.export();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() {
|
|
if(tree == null) return null;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE entry = first.export();
|
|
removeNode(first);
|
|
return entry;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() {
|
|
if(tree == null) return null;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE entry = last.export();
|
|
removeNode(last);
|
|
return entry;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE FIRST_ENTRY_VALUE() {
|
|
if(tree == null) throw new NoSuchElementException();
|
|
return first.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE LAST_ENTRY_VALUE() {
|
|
if(tree == null) throw new NoSuchElementException();
|
|
return last.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE REMOVE_VALUE(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) return getDefaultReturnValue();
|
|
VALUE_TYPE value = entry.value;
|
|
removeNode(entry);
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE REMOVE_VALUEOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) return defaultValue;
|
|
VALUE_TYPE value = entry.value;
|
|
removeNode(entry);
|
|
return value;
|
|
}
|
|
|
|
#if TYPE_OBJECT && VALUE_OBJECT
|
|
@Override
|
|
public boolean remove(Object key, Object value) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode((CLASS_TYPE)key);
|
|
if(entry == null || !Objects.equals(value, entry.value)) return false;
|
|
removeNode(entry);
|
|
return true;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public boolean remove(KEY_TYPE key, VALUE_TYPE value) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null || entry.value != value) return false;
|
|
removeNode(entry);
|
|
return true;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public boolean replace(KEY_TYPE key, VALUE_TYPE oldValue, VALUE_TYPE newValue) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null || entry.value != oldValue) return false;
|
|
entry.value = newValue;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE replace(KEY_TYPE key, VALUE_TYPE value) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) return getDefaultReturnValue();
|
|
VALUE_TYPE oldValue = entry.value;
|
|
entry.value = value;
|
|
return oldValue;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE COMPUTE(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) {
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
|
|
#if VALUE_OBJECT
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
#endif
|
|
put(key, newValue);
|
|
return newValue;
|
|
}
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
|
|
#if VALUE_OBJECT
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
removeNode(entry);
|
|
return newValue;
|
|
}
|
|
#endif
|
|
entry.value = newValue;
|
|
return newValue;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE COMPUTE_IF_ABSENT(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) {
|
|
VALUE_TYPE newValue = mappingFunction.APPLY(key);
|
|
#if VALUE_OBJECT
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
#endif
|
|
put(key, newValue);
|
|
return newValue;
|
|
}
|
|
#if VALUE_OBJECT
|
|
if(Objects.equals(entry.value, getDefaultReturnValue())) {
|
|
VALUE_TYPE newValue = mappingFunction.APPLY(key);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
entry.value = newValue;
|
|
}
|
|
#endif
|
|
return entry.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE SUPPLY_IF_ABSENT(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
|
|
Objects.requireNonNull(valueProvider);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) {
|
|
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
|
|
#if VALUE_OBJECT
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
#endif
|
|
put(key, newValue);
|
|
return newValue;
|
|
}
|
|
#if VALUE_OBJECT
|
|
if(VALUE_EQUALS(entry.value, getDefaultReturnValue())) {
|
|
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
entry.value = newValue;
|
|
}
|
|
#endif
|
|
return entry.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
#if !VALUE_OBJECT
|
|
if(entry == null) return getDefaultReturnValue();
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
|
|
#else
|
|
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
removeNode(entry);
|
|
return newValue;
|
|
}
|
|
#endif
|
|
entry.value = newValue;
|
|
return newValue;
|
|
}
|
|
|
|
#if !VALUE_OBJECT
|
|
@Override
|
|
public VALUE_TYPE COMPUTENonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) {
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, getDefaultReturnValue());
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
put(key, newValue);
|
|
return newValue;
|
|
}
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
removeNode(entry);
|
|
return newValue;
|
|
}
|
|
entry.value = newValue;
|
|
return newValue;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE COMPUTE_IF_ABSENTNonDefault(KEY_TYPE key, FUNCTION KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) {
|
|
VALUE_TYPE newValue = mappingFunction.APPLY(key);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
put(key, newValue);
|
|
return newValue;
|
|
}
|
|
if(Objects.equals(entry.value, getDefaultReturnValue())) {
|
|
VALUE_TYPE newValue = mappingFunction.APPLY(key);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
entry.value = newValue;
|
|
}
|
|
return entry.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE SUPPLY_IF_ABSENTNonDefault(KEY_TYPE key, VALUE_SUPPLIER VALUE_GENERIC_TYPE valueProvider) {
|
|
Objects.requireNonNull(valueProvider);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null) {
|
|
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
put(key, newValue);
|
|
return newValue;
|
|
}
|
|
if(VALUE_EQUALS(entry.value, getDefaultReturnValue())) {
|
|
VALUE_TYPE newValue = valueProvider.VALUE_SUPPLY_GET();
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) return newValue;
|
|
entry.value = newValue;
|
|
}
|
|
return entry.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE COMPUTE_IF_PRESENTNonDefault(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
|
|
VALUE_TYPE newValue = mappingFunction.APPLY_VALUE(key, entry.value);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
removeNode(entry);
|
|
return newValue;
|
|
}
|
|
entry.value = newValue;
|
|
return newValue;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public VALUE_TYPE MERGE(KEY_TYPE key, VALUE_TYPE value, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
validate(key);
|
|
#endif
|
|
Node KEY_VALUE_GENERIC_TYPE entry = findNode(key);
|
|
VALUE_TYPE newValue = entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue()) ? value : mappingFunction.APPLY_VALUE(entry.value, value);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
if(entry != null)
|
|
removeNode(entry);
|
|
}
|
|
else if(entry == null) put(key, newValue);
|
|
else entry.value = newValue;
|
|
return newValue;
|
|
}
|
|
|
|
@Override
|
|
public void BULK_MERGE(MAP KEY_VALUE_GENERIC_TYPE m, VALUE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
for(MAP.Entry KEY_VALUE_GENERIC_TYPE entry : getFastIterable(m)) {
|
|
KEY_TYPE key = entry.ENTRY_KEY();
|
|
Node KEY_VALUE_GENERIC_TYPE subEntry = findNode(key);
|
|
VALUE_TYPE newValue = subEntry == null || VALUE_EQUALS(subEntry.value, getDefaultReturnValue()) ? entry.ENTRY_VALUE() : mappingFunction.APPLY_VALUE(subEntry.value, entry.ENTRY_VALUE());
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
if(subEntry != null)
|
|
removeNode(subEntry);
|
|
}
|
|
else if(subEntry == null) put(key, newValue);
|
|
else subEntry.value = newValue;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void forEach(BI_CONSUMER KEY_VALUE_GENERIC_TYPE action) {
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(entry.key, entry.value);
|
|
}
|
|
|
|
@Override
|
|
public int size() { return size; }
|
|
|
|
@Override
|
|
public void clear() {
|
|
size = 0;
|
|
first = null;
|
|
last = null;
|
|
tree = null;
|
|
}
|
|
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE keyIterator() {
|
|
return new AscendingKeyIterator(first);
|
|
}
|
|
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE keyIterator(KEY_TYPE element) {
|
|
return new AscendingKeyIterator(findNode(element));
|
|
}
|
|
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE descendingKeyIterator() {
|
|
return new DescendingKeyIterator(last);
|
|
}
|
|
|
|
@Override
|
|
public RB_TREE_MAP KEY_VALUE_GENERIC_TYPE copy() {
|
|
RB_TREE_MAP KEY_VALUE_GENERIC_TYPE set = new RB_TREE_MAPKV_BRACES();
|
|
set.size = size;
|
|
if(tree != null) {
|
|
set.tree = tree.copy();
|
|
Node KEY_VALUE_GENERIC_TYPE lastFound = null;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = tree;entry != null;entry = entry.left) lastFound = entry;
|
|
set.first = lastFound;
|
|
lastFound = null;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = tree;entry != null;entry = entry.right) lastFound = entry;
|
|
set.last = lastFound;
|
|
}
|
|
return set;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet() {
|
|
return navigableKeySet();
|
|
}
|
|
|
|
@Override
|
|
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
|
|
if(entrySet == null) entrySet = new EntrySet();
|
|
return entrySet;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
|
|
if(values == null) values = new Values();
|
|
return values;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() {
|
|
if(keySet == null) keySet = new KeySetKV_BRACES(this);
|
|
return keySet;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() {
|
|
return new DescendingNaivgableSubMapKV_BRACES(this, true, EMPTY_KEY_VALUE, true, true, EMPTY_KEY_VALUE, true);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() {
|
|
return descendingMap().navigableKeySet();
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, boolean fromInclusive, KEY_TYPE toKey, boolean toInclusive) {
|
|
return new AscendingNaivgableSubMapKV_BRACES(this, false, fromKey, fromInclusive, false, toKey, toInclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey, boolean inclusive) {
|
|
return new AscendingNaivgableSubMapKV_BRACES(this, true, EMPTY_KEY_VALUE, true, false, toKey, inclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey, boolean inclusive) {
|
|
return new AscendingNaivgableSubMapKV_BRACES(this, false, fromKey, inclusive, true, EMPTY_KEY_VALUE, true);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE lowerKey(KEY_TYPE e) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findLowerNode(e);
|
|
return node != null ? node.key : getDefaultMinValue();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE floorKey(KEY_TYPE e) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findFloorNode(e);
|
|
return node != null ? node.key : getDefaultMinValue();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE higherKey(KEY_TYPE e) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findHigherNode(e);
|
|
return node != null ? node.key : getDefaultMaxValue();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE ceilingKey(KEY_TYPE e) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findCeilingNode(e);
|
|
return node != null ? node.key : getDefaultMaxValue();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findLowerNode(key);
|
|
return node != null ? node.export() : null;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findHigherNode(key);
|
|
return node != null ? node.export() : null;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findFloorNode(key);
|
|
return node != null ? node.export() : null;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = findCeilingNode(key);
|
|
return node != null ? node.export() : null;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE findLowerNode(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = tree;
|
|
while(entry != null) {
|
|
if(compare(key, entry.key) > 0) {
|
|
if(entry.right != null) entry = entry.right;
|
|
else return entry;
|
|
}
|
|
else {
|
|
if(entry.left != null) entry = entry.left;
|
|
else {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = entry.parent;
|
|
while(parent != null && parent.left == entry) {
|
|
entry = parent;
|
|
parent = parent.parent;
|
|
}
|
|
return parent;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE findFloorNode(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = tree;
|
|
int compare;
|
|
while(entry != null) {
|
|
if((compare = compare(key, entry.key)) > 0) {
|
|
if(entry.right == null) break;
|
|
entry = entry.right;
|
|
continue;
|
|
}
|
|
else if(compare < 0) {
|
|
if(entry.left != null) entry = entry.left;
|
|
else {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = entry.parent;
|
|
while(parent != null && parent.left == entry) {
|
|
entry = parent;
|
|
parent = parent.parent;
|
|
}
|
|
return parent;
|
|
}
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE findCeilingNode(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = tree;
|
|
int compare;
|
|
while(entry != null) {
|
|
if((compare = compare(key, entry.key)) < 0) {
|
|
if(entry.left == null) break;
|
|
entry = entry.left;
|
|
continue;
|
|
}
|
|
else if(compare > 0) {
|
|
if(entry.right != null) entry = entry.right;
|
|
else {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = entry.parent;
|
|
while(parent != null && parent.right == entry) {
|
|
entry = parent;
|
|
parent = parent.parent;
|
|
}
|
|
return parent;
|
|
}
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE findHigherNode(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = tree;
|
|
while(entry != null) {
|
|
if(compare(key, entry.key) < 0) {
|
|
if(entry.left != null) entry = entry.left;
|
|
else return entry;
|
|
}
|
|
else {
|
|
if(entry.right != null) entry = entry.right;
|
|
else {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = entry.parent;
|
|
while(parent != null && parent.right == entry) {
|
|
entry = parent;
|
|
parent = parent.parent;
|
|
}
|
|
return parent;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE findNode(KEY_TYPE key) {
|
|
Node KEY_VALUE_GENERIC_TYPE node = tree;
|
|
int compare;
|
|
while(node != null) {
|
|
if((compare = compare(key, node.key)) == 0) return node;
|
|
if(compare < 0) node = node.left;
|
|
else node = node.right;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected void removeNode(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
size--;
|
|
if(entry.needsSuccessor()) {
|
|
Node KEY_VALUE_GENERIC_TYPE successor = entry.next();
|
|
entry.key = successor.key;
|
|
entry.value = successor.value;
|
|
entry = successor;
|
|
}
|
|
Node KEY_VALUE_GENERIC_TYPE replacement = entry.left != null ? entry.left : entry.right;
|
|
if(replacement != null) {
|
|
if(entry.replace(replacement)) tree = replacement;
|
|
if(entry == first) first = replacement;
|
|
if(entry == last) last = entry.right != null ? entry.right : replacement;
|
|
entry.left = entry.right = entry.parent = null;
|
|
if(entry.isBlack()) fixAfterDeletion(replacement);
|
|
}
|
|
else if(entry.parent == null) tree = first = last = null;
|
|
else {
|
|
if(entry.isBlack())
|
|
fixAfterDeletion(entry);
|
|
entry.replace(null);
|
|
if(entry.parent != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = entry.parent;
|
|
if(entry == first) first = parent.left != null ? parent.left : parent;
|
|
if(entry == last) last = entry.right != null ? parent.right : parent;
|
|
}
|
|
entry.parent = null;
|
|
}
|
|
}
|
|
|
|
protected void validate(KEY_TYPE k) { compare(k, k); }
|
|
protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
|
|
protected static GENERIC_KEY_VALUE_BRACES boolean isBlack(Node KEY_VALUE_GENERIC_TYPE p) { return p == null || p.isBlack(); }
|
|
protected static GENERIC_KEY_VALUE_BRACES Node KEY_VALUE_GENERIC_TYPE parentOf(Node KEY_VALUE_GENERIC_TYPE p) { return (p == null ? null : p.parent); }
|
|
protected static GENERIC_KEY_VALUE_BRACES void setBlack(Node KEY_VALUE_GENERIC_TYPE p, boolean c) { if(p != null) p.setBlack(c); }
|
|
protected static GENERIC_KEY_VALUE_BRACES Node KEY_VALUE_GENERIC_TYPE leftOf(Node KEY_VALUE_GENERIC_TYPE p) { return p == null ? null : p.left; }
|
|
protected static GENERIC_KEY_VALUE_BRACES Node KEY_VALUE_GENERIC_TYPE rightOf(Node KEY_VALUE_GENERIC_TYPE p) { return (p == null) ? null : p.right; }
|
|
|
|
protected void rotateLeft(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
if(entry != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE right = entry.right;
|
|
entry.right = right.left;
|
|
if(right.left != null) right.left.parent = entry;
|
|
right.parent = entry.parent;
|
|
if(entry.parent == null) tree = right;
|
|
else if(entry.parent.left == entry) entry.parent.left = right;
|
|
else entry.parent.right = right;
|
|
right.left = entry;
|
|
entry.parent = right;
|
|
}
|
|
}
|
|
|
|
protected void rotateRight(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
if(entry != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE left = entry.left;
|
|
entry.left = left.right;
|
|
if(left.right != null) left.right.parent = entry;
|
|
left.parent = entry.parent;
|
|
if(entry.parent == null) tree = left;
|
|
else if(entry.parent.right == entry) entry.parent.right = left;
|
|
else entry.parent.left = left;
|
|
left.right = entry;
|
|
entry.parent = left;
|
|
}
|
|
}
|
|
|
|
protected void fixAfterInsertion(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
entry.setBlack(false);
|
|
while(entry != null && entry != tree && !entry.parent.isBlack()) {
|
|
if(parentOf(entry) == leftOf(parentOf(parentOf(entry)))) {
|
|
Node KEY_VALUE_GENERIC_TYPE y = rightOf(parentOf(parentOf(entry)));
|
|
if(!isBlack(y)) {
|
|
setBlack(parentOf(entry), true);
|
|
setBlack(y, true);
|
|
setBlack(parentOf(parentOf(entry)), false);
|
|
entry = parentOf(parentOf(entry));
|
|
}
|
|
else {
|
|
if(entry == rightOf(parentOf(entry))) {
|
|
entry = parentOf(entry);
|
|
rotateLeft(entry);
|
|
}
|
|
setBlack(parentOf(entry), true);
|
|
setBlack(parentOf(parentOf(entry)), false);
|
|
rotateRight(parentOf(parentOf(entry)));
|
|
}
|
|
}
|
|
else {
|
|
Node KEY_VALUE_GENERIC_TYPE y = leftOf(parentOf(parentOf(entry)));
|
|
if(!isBlack(y)) {
|
|
setBlack(parentOf(entry), true);
|
|
setBlack(y, true);
|
|
setBlack(parentOf(parentOf(entry)), false);
|
|
entry = parentOf(parentOf(entry));
|
|
}
|
|
else {
|
|
if(entry == leftOf(parentOf(entry))) {
|
|
entry = parentOf(entry);
|
|
rotateRight(entry);
|
|
}
|
|
setBlack(parentOf(entry), true);
|
|
setBlack(parentOf(parentOf(entry)), false);
|
|
rotateLeft(parentOf(parentOf(entry)));
|
|
}
|
|
}
|
|
}
|
|
tree.setBlack(true);
|
|
}
|
|
|
|
protected void fixAfterDeletion(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
while(entry != tree && isBlack(entry)) {
|
|
if(entry == leftOf(parentOf(entry))) {
|
|
Node KEY_VALUE_GENERIC_TYPE sib = rightOf(parentOf(entry));
|
|
if(!isBlack(sib)) {
|
|
setBlack(sib, true);
|
|
setBlack(parentOf(entry), false);
|
|
rotateLeft(parentOf(entry));
|
|
sib = rightOf(parentOf(entry));
|
|
}
|
|
if(isBlack(leftOf(sib)) && isBlack(rightOf(sib))) {
|
|
setBlack(sib, false);
|
|
entry = parentOf(entry);
|
|
}
|
|
else {
|
|
if(isBlack(rightOf(sib))) {
|
|
setBlack(leftOf(sib), true);
|
|
setBlack(sib, false);
|
|
rotateRight(sib);
|
|
sib = rightOf(parentOf(entry));
|
|
}
|
|
setBlack(sib, isBlack(parentOf(entry)));
|
|
setBlack(parentOf(entry), true);
|
|
setBlack(rightOf(sib), true);
|
|
rotateLeft(parentOf(entry));
|
|
entry = tree;
|
|
}
|
|
}
|
|
else {
|
|
Node KEY_VALUE_GENERIC_TYPE sib = leftOf(parentOf(entry));
|
|
if(!isBlack(sib)) {
|
|
setBlack(sib, true);
|
|
setBlack(parentOf(entry), false);
|
|
rotateRight(parentOf(entry));
|
|
sib = leftOf(parentOf(entry));
|
|
}
|
|
if(isBlack(rightOf(sib)) && isBlack(leftOf(sib))) {
|
|
setBlack(sib, false);
|
|
entry = parentOf(entry);
|
|
}
|
|
else {
|
|
if(isBlack(leftOf(sib))) {
|
|
setBlack(rightOf(sib), true);
|
|
setBlack(sib, false);
|
|
rotateLeft(sib);
|
|
sib = leftOf(parentOf(entry));
|
|
}
|
|
setBlack(sib, isBlack(parentOf(entry)));
|
|
setBlack(parentOf(entry), true);
|
|
setBlack(leftOf(sib), true);
|
|
rotateRight(parentOf(entry));
|
|
entry = tree;
|
|
}
|
|
}
|
|
}
|
|
setBlack(entry, true);
|
|
}
|
|
|
|
static class KeySet KEY_VALUE_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
|
|
{
|
|
NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map;
|
|
|
|
public KeySet(NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE map) {
|
|
this.map = map;
|
|
}
|
|
|
|
#if !TYPE_OBJECT
|
|
@Override
|
|
public void setDefaultMaxValue(KEY_TYPE e) { map.setDefaultMaxValue(e); }
|
|
@Override
|
|
public KEY_TYPE getDefaultMaxValue() { return map.getDefaultMaxValue(); }
|
|
@Override
|
|
public void setDefaultMinValue(KEY_TYPE e) { map.setDefaultMinValue(e); }
|
|
@Override
|
|
public KEY_TYPE getDefaultMinValue() { return map.getDefaultMinValue(); }
|
|
#endif
|
|
@Override
|
|
public KEY_TYPE lower(KEY_TYPE e) { return map.lowerKey(e); }
|
|
@Override
|
|
public KEY_TYPE floor(KEY_TYPE e) { return map.floorKey(e); }
|
|
@Override
|
|
public KEY_TYPE ceiling(KEY_TYPE e) { return map.ceilingKey(e); }
|
|
@Override
|
|
public KEY_TYPE higher(KEY_TYPE e) { return map.higherKey(e); }
|
|
|
|
#if !TYPE_OBJECT
|
|
@Override
|
|
public CLASS_TYPE lower(CLASS_TYPE e) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE node = map.lowerEntry(OBJ_TO_KEY(e));
|
|
return node != null ? node.getKey() : null;
|
|
}
|
|
|
|
@Override
|
|
public CLASS_TYPE floor(CLASS_TYPE e) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE node = map.floorEntry(OBJ_TO_KEY(e));
|
|
return node != null ? node.getKey() : null;
|
|
}
|
|
|
|
@Override
|
|
public CLASS_TYPE higher(CLASS_TYPE e) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE node = map.higherEntry(OBJ_TO_KEY(e));
|
|
return node != null ? node.getKey() : null;
|
|
}
|
|
|
|
@Override
|
|
public CLASS_TYPE ceiling(CLASS_TYPE e) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE node = map.ceilingEntry(OBJ_TO_KEY(e));
|
|
return node != null ? node.getKey() : null;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public KEY_TYPE POLL_FIRST_KEY() { return map.POLL_FIRST_ENTRY_KEY(); }
|
|
@Override
|
|
public KEY_TYPE POLL_LAST_KEY() { return map.POLL_LAST_ENTRY_KEY(); }
|
|
@Override
|
|
public COMPARATOR KEY_GENERIC_TYPE comparator() { return map.comparator(); }
|
|
@Override
|
|
public KEY_TYPE FIRST_KEY() { return map.FIRST_ENTRY_KEY(); }
|
|
@Override
|
|
public KEY_TYPE LAST_KEY() { return map.LAST_ENTRY_KEY(); }
|
|
@Override
|
|
public void clear() { map.clear(); }
|
|
|
|
#if TYPE_OBJECT
|
|
@Override
|
|
public boolean remove(Object o) {
|
|
int oldSize = map.size();
|
|
map.remove(o);
|
|
return oldSize != map.size();
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public boolean remove(KEY_TYPE o) {
|
|
int oldSize = map.size();
|
|
map.remove(o);
|
|
return oldSize != map.size();
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public boolean add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
|
|
@Override
|
|
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
|
|
if(map instanceof RB_TREE_MAP) return ((RB_TREE_MAP KEY_VALUE_GENERIC_TYPE)map).keyIterator(fromElement);
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).keyIterator(fromElement);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { return new KeySetKV_BRACES(map.subMap(fromElement, fromInclusive, toElement, toInclusive)); }
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) { return new KeySetKV_BRACES(map.headMap(toElement, inclusive)); }
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) { return new KeySetKV_BRACES(map.tailMap(fromElement, inclusive)); }
|
|
|
|
@Override
|
|
public BI_ITERATOR KEY_GENERIC_TYPE iterator() {
|
|
if(map instanceof RB_TREE_MAP) return ((RB_TREE_MAP KEY_VALUE_GENERIC_TYPE)map).keyIterator();
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).keyIterator();
|
|
}
|
|
|
|
@Override
|
|
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() {
|
|
if(map instanceof RB_TREE_MAP) return ((RB_TREE_MAP KEY_VALUE_GENERIC_TYPE)map).descendingKeyIterator();
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).descendingKeyIterator();
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE start() {
|
|
if(map instanceof RB_TREE_MAP) return ((RB_TREE_MAP KEY_VALUE_GENERIC_TYPE)map).first;
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).subLowest();
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE end() {
|
|
if(map instanceof RB_TREE_MAP) return null;
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).subHighest();
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE next(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
if(map instanceof RB_TREE_MAP) return entry.next();
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).next(entry);
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE previous(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
if(map instanceof RB_TREE_MAP) return entry.previous();
|
|
return ((NavigableSubMap KEY_VALUE_GENERIC_TYPE)map).previous(entry);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { return new KeySetKV_BRACES(map.descendingMap()); }
|
|
@Override
|
|
public KeySet KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
|
|
@Override
|
|
public boolean isEmpty() { return map.isEmpty(); }
|
|
@Override
|
|
public int size() { return map.size(); }
|
|
|
|
@Override
|
|
public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
action.accept(entry.key);
|
|
}
|
|
|
|
@Override
|
|
public void forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
int index = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
action.accept(index++, entry.key);
|
|
}
|
|
|
|
@Override
|
|
public <E> void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE<E> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
action.accept(input, entry.key);
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
if(filter.test(entry.key)) return true;
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
if(filter.test(entry.key)) return false;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
if(!filter.test(entry.key)) return false;
|
|
return true;
|
|
}
|
|
|
|
#if !TYPE_OBJECT
|
|
@Override
|
|
public KEY_TYPE reduce(KEY_TYPE identity, SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
|
|
Objects.requireNonNull(operator);
|
|
KEY_TYPE state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
state = operator.APPLY_KEY_VALUE(state, entry.key);
|
|
return state;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public <KEY_SPECIAL_TYPE> KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction<KEY_SPECIAL_TYPE, KEY_TYPE, KEY_SPECIAL_TYPE> operator) {
|
|
Objects.requireNonNull(operator);
|
|
KEY_SPECIAL_TYPE state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
state = operator.apply(state, entry.key);
|
|
return state;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public KEY_TYPE reduce(SINGLE_UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) {
|
|
Objects.requireNonNull(operator);
|
|
KEY_TYPE state = EMPTY_KEY_VALUE;
|
|
boolean empty = true;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry)) {
|
|
if(empty) {
|
|
empty = false;
|
|
state = entry.key;
|
|
continue;
|
|
}
|
|
state = operator.APPLY_KEY_VALUE(state, entry.key);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
if(filter.test(entry.key)) return entry.key;
|
|
return EMPTY_KEY_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public int count(PREDICATE KEY_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
int result = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = start(), end = end();entry != null && (end == null || (end != previous(entry)));entry = next(entry))
|
|
if(filter.test(entry.key)) result++;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
static class AscendingNaivgableSubMap KEY_VALUE_GENERIC_TYPE extends NavigableSubMap KEY_VALUE_GENERIC_TYPE
|
|
{
|
|
AscendingNaivgableSubMap(RB_TREE_MAP KEY_VALUE_GENERIC_TYPE map, boolean fromStart, KEY_TYPE lo, boolean loInclusive, boolean toEnd, KEY_TYPE hi, boolean hiInclusive) {
|
|
super(map, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() {
|
|
if(inverse == null) inverse = new DescendingNaivgableSubMapKV_BRACES(map, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
|
|
return inverse;
|
|
}
|
|
|
|
@Override
|
|
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
|
|
if(entrySet == null) entrySet = new AscendingSubEntrySet();
|
|
return entrySet;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() {
|
|
if(keySet == null) keySet = new KeySetKV_BRACES(this);
|
|
return keySet;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet() {
|
|
return navigableKeySet();
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, boolean fromInclusive, KEY_TYPE toKey, boolean toInclusive) {
|
|
if (!inRange(fromKey, fromInclusive)) throw new IllegalArgumentException("fromKey out of range");
|
|
if (!inRange(toKey, toInclusive)) throw new IllegalArgumentException("toKey out of range");
|
|
return new AscendingNaivgableSubMapKV_BRACES(map, false, fromKey, fromInclusive, false, toKey, toInclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey, boolean inclusive) {
|
|
if (!inRange(toKey, inclusive)) throw new IllegalArgumentException("toKey out of range");
|
|
return new AscendingNaivgableSubMapKV_BRACES(map, fromStart, lo, loInclusive, false, toKey, inclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey, boolean inclusive) {
|
|
if (!inRange(fromKey, inclusive)) throw new IllegalArgumentException("fromKey out of range");
|
|
return new AscendingNaivgableSubMapKV_BRACES(map, false, fromKey, inclusive, toEnd, hi, hiInclusive);
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subLowest() { return absLowest(); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subHighest() { return absHighest(); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subCeiling(KEY_TYPE key) { return absCeiling(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subHigher(KEY_TYPE key) { return absHigher(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subFloor(KEY_TYPE key) { return absFloor(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subLower(KEY_TYPE key) { return absLower(key); }
|
|
|
|
@Override
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE keyIterator() {
|
|
return new AcsendingSubKeyIterator(absLowest(), absHighFence(), absLowFence());
|
|
}
|
|
@Override
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE keyIterator(KEY_TYPE element) {
|
|
return new AcsendingSubKeyIterator(absLower(element), absHighFence(), absLowFence());
|
|
}
|
|
|
|
@Override
|
|
protected VALUE_BI_ITERATOR VALUE_GENERIC_TYPE valueIterator() {
|
|
return new AcsendingSubValueIterator(absLowest(), absHighFence(), absLowFence());
|
|
}
|
|
|
|
@Override
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE descendingKeyIterator() {
|
|
return new DecsendingSubKeyIterator(absHighest(), absLowFence(), absHighFence());
|
|
}
|
|
|
|
class AscendingSubEntrySet extends SubEntrySet {
|
|
@Override
|
|
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
|
|
return new AcsendingSubEntryIterator(absLowest(), absHighFence(), absLowFence());
|
|
}
|
|
}
|
|
}
|
|
|
|
static class DescendingNaivgableSubMap KEY_VALUE_GENERIC_TYPE extends NavigableSubMap KEY_VALUE_GENERIC_TYPE
|
|
{
|
|
COMPARATOR KEY_GENERIC_TYPE comparator;
|
|
DescendingNaivgableSubMap(RB_TREE_MAP KEY_VALUE_GENERIC_TYPE map, boolean fromStart, KEY_TYPE lo, boolean loInclusive, boolean toEnd, KEY_TYPE hi, boolean hiInclusive) {
|
|
super(map, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
|
|
#if TYPE_OBJECT
|
|
comparator = Collections.reverseOrder(map.comparator());
|
|
#else
|
|
comparator = map.comparator() == null ? COMPARATOR.of(Collections.reverseOrder()) : map.comparator().reversed();
|
|
#endif
|
|
}
|
|
|
|
@Override
|
|
public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; }
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE descendingMap() {
|
|
if(inverse == null) inverse = new AscendingNaivgableSubMapKV_BRACES(map, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
|
|
return inverse;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE navigableKeySet() {
|
|
if(keySet == null) keySet = new KeySetKV_BRACES(this);
|
|
return keySet;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet() {
|
|
return navigableKeySet();
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE subMap(KEY_TYPE fromKey, boolean fromInclusive, KEY_TYPE toKey, boolean toInclusive) {
|
|
if (!inRange(fromKey, fromInclusive)) throw new IllegalArgumentException("fromKey out of range");
|
|
if (!inRange(toKey, toInclusive)) throw new IllegalArgumentException("toKey out of range");
|
|
return new DescendingNaivgableSubMapKV_BRACES(map, false, toKey, toInclusive, false, fromKey, fromInclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE headMap(KEY_TYPE toKey, boolean inclusive) {
|
|
if (!inRange(toKey, inclusive)) throw new IllegalArgumentException("toKey out of range");
|
|
return new DescendingNaivgableSubMapKV_BRACES(map, false, toKey, inclusive, toEnd, hi, hiInclusive);
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE tailMap(KEY_TYPE fromKey, boolean inclusive) {
|
|
if (!inRange(fromKey, inclusive)) throw new IllegalArgumentException("fromKey out of range");
|
|
return new DescendingNaivgableSubMapKV_BRACES(map, fromStart, lo, loInclusive, false, fromKey, inclusive);
|
|
}
|
|
|
|
@Override
|
|
public ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> ENTRY_SET() {
|
|
if(entrySet == null) entrySet = new DescendingSubEntrySet();
|
|
return entrySet;
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subLowest() { return absHighest(); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subHighest() { return absLowest(); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subCeiling(KEY_TYPE key) { return absFloor(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subHigher(KEY_TYPE key) { return absLower(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subFloor(KEY_TYPE key) { return absCeiling(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE subLower(KEY_TYPE key) { return absHigher(key); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE next(Node KEY_VALUE_GENERIC_TYPE entry) { return entry.previous(); }
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE previous(Node KEY_VALUE_GENERIC_TYPE entry) { return entry.next(); }
|
|
|
|
@Override
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE keyIterator() {
|
|
return new DecsendingSubKeyIterator(absHighest(), absLowFence(), absHighFence());
|
|
}
|
|
|
|
@Override
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE keyIterator(KEY_TYPE element) {
|
|
return new DecsendingSubKeyIterator(absHigher(element), absLowFence(), absHighFence());
|
|
}
|
|
|
|
@Override
|
|
protected VALUE_BI_ITERATOR VALUE_GENERIC_TYPE valueIterator() {
|
|
return new DecsendingSubValueIterator(absHighest(), absLowFence(), absHighFence());
|
|
}
|
|
|
|
@Override
|
|
protected BI_ITERATOR KEY_GENERIC_TYPE descendingKeyIterator() {
|
|
return new AcsendingSubKeyIterator(absLowest(), absHighFence(), absLowFence());
|
|
}
|
|
|
|
class DescendingSubEntrySet extends SubEntrySet {
|
|
@Override
|
|
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
|
|
return new DecsendingSubEntryIterator(absHighest(), absLowFence(), absHighFence());
|
|
}
|
|
}
|
|
}
|
|
|
|
static abstract class NavigableSubMap KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE
|
|
{
|
|
final RB_TREE_MAP KEY_VALUE_GENERIC_TYPE map;
|
|
final KEY_TYPE lo, hi;
|
|
final boolean fromStart, toEnd;
|
|
final boolean loInclusive, hiInclusive;
|
|
|
|
NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE inverse;
|
|
NAVIGABLE_SET KEY_GENERIC_TYPE keySet;
|
|
ObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> entrySet;
|
|
VALUE_COLLECTION VALUE_GENERIC_TYPE values;
|
|
|
|
NavigableSubMap(RB_TREE_MAP KEY_VALUE_GENERIC_TYPE map, boolean fromStart, KEY_TYPE lo, boolean loInclusive, boolean toEnd, KEY_TYPE hi, boolean hiInclusive) {
|
|
if (!fromStart && !toEnd) {
|
|
if (map.compare(lo, hi) > 0) throw new IllegalArgumentException("fromKey > toKey");
|
|
}
|
|
else {
|
|
if (!fromStart) map.validate(lo);
|
|
if (!toEnd) map.validate(hi);
|
|
}
|
|
this.map = map;
|
|
this.fromStart = fromStart;
|
|
this.lo = lo;
|
|
this.loInclusive = loInclusive;
|
|
this.toEnd = toEnd;
|
|
this.hi = hi;
|
|
this.hiInclusive = hiInclusive;
|
|
}
|
|
|
|
#if TYPE_OBJECT
|
|
public KEY_TYPE getDefaultMaxValue() { return map.getDefaultMaxValue(); }
|
|
public KEY_TYPE getDefaultMinValue() { return map.getDefaultMinValue(); }
|
|
#else
|
|
@Override
|
|
public void setDefaultMaxValue(KEY_TYPE e) { map.setDefaultMaxValue(e); }
|
|
@Override
|
|
public KEY_TYPE getDefaultMaxValue() { return map.getDefaultMaxValue(); }
|
|
@Override
|
|
public void setDefaultMinValue(KEY_TYPE e) { map.setDefaultMinValue(e); }
|
|
@Override
|
|
public KEY_TYPE getDefaultMinValue() { return map.getDefaultMinValue(); }
|
|
#endif
|
|
protected boolean isNullComparator() { return map.comparator() == null; }
|
|
|
|
@Override
|
|
public ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE setDefaultReturnValue(VALUE_TYPE v) {
|
|
map.setDefaultReturnValue(v);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE getDefaultReturnValue() { return map.getDefaultReturnValue(); }
|
|
|
|
@Override
|
|
public VALUE_COLLECTION VALUE_GENERIC_TYPE values() {
|
|
if(values == null) values = new SubMapValues();
|
|
return values;
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingKeySet() {
|
|
return descendingMap().navigableKeySet();
|
|
}
|
|
|
|
@Override
|
|
public NAVIGABLE_SET KEY_GENERIC_TYPE keySet() {
|
|
return navigableKeySet();
|
|
}
|
|
|
|
protected abstract Node KEY_VALUE_GENERIC_TYPE subLowest();
|
|
protected abstract Node KEY_VALUE_GENERIC_TYPE subHighest();
|
|
protected abstract Node KEY_VALUE_GENERIC_TYPE subCeiling(KEY_TYPE key);
|
|
protected abstract Node KEY_VALUE_GENERIC_TYPE subHigher(KEY_TYPE key);
|
|
protected abstract Node KEY_VALUE_GENERIC_TYPE subFloor(KEY_TYPE key);
|
|
protected abstract Node KEY_VALUE_GENERIC_TYPE subLower(KEY_TYPE key);
|
|
protected abstract BI_ITERATOR KEY_GENERIC_TYPE keyIterator();
|
|
protected abstract BI_ITERATOR KEY_GENERIC_TYPE keyIterator(KEY_TYPE element);
|
|
protected abstract VALUE_BI_ITERATOR VALUE_GENERIC_TYPE valueIterator();
|
|
protected abstract BI_ITERATOR KEY_GENERIC_TYPE descendingKeyIterator();
|
|
protected KEY_TYPE lowKeyOrNull(Node KEY_VALUE_GENERIC_TYPE entry) { return entry == null ? getDefaultMinValue() : entry.key; }
|
|
protected KEY_TYPE highKeyOrNull(Node KEY_VALUE_GENERIC_TYPE entry) { return entry == null ? getDefaultMaxValue() : entry.key; }
|
|
protected Node KEY_VALUE_GENERIC_TYPE next(Node KEY_VALUE_GENERIC_TYPE entry) { return entry.next(); }
|
|
protected Node KEY_VALUE_GENERIC_TYPE previous(Node KEY_VALUE_GENERIC_TYPE entry) { return entry.previous(); }
|
|
|
|
protected boolean tooLow(KEY_TYPE key) {
|
|
if (!fromStart) {
|
|
int c = map.compare(key, lo);
|
|
if (c < 0 || (c == 0 && !loInclusive)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected boolean tooHigh(KEY_TYPE key) {
|
|
if (!toEnd) {
|
|
int c = map.compare(key, hi);
|
|
if (c > 0 || (c == 0 && !hiInclusive)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
protected boolean inRange(KEY_TYPE key) { return !tooLow(key) && !tooHigh(key); }
|
|
protected boolean inClosedRange(KEY_TYPE key) { return (fromStart || map.compare(key, lo) >= 0) && (toEnd || map.compare(hi, key) >= 0); }
|
|
protected boolean inRange(KEY_TYPE key, boolean inclusive) { return inclusive ? inRange(key) : inClosedRange(key); }
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absLowest() {
|
|
Node KEY_VALUE_GENERIC_TYPE e = (fromStart ? map.first : (loInclusive ? map.findCeilingNode(lo) : map.findHigherNode(lo)));
|
|
return (e == null || tooHigh(e.key)) ? null : e;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absHighest() {
|
|
Node KEY_VALUE_GENERIC_TYPE e = (toEnd ? map.last : (hiInclusive ? map.findFloorNode(hi) : map.findLowerNode(hi)));
|
|
return (e == null || tooLow(e.key)) ? null : e;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absCeiling(KEY_TYPE key) {
|
|
if (tooLow(key)) return absLowest();
|
|
Node KEY_VALUE_GENERIC_TYPE e = map.findCeilingNode(key);
|
|
return (e == null || tooHigh(e.key)) ? null : e;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absHigher(KEY_TYPE key) {
|
|
if (tooLow(key)) return absLowest();
|
|
Node KEY_VALUE_GENERIC_TYPE e = map.findHigherNode(key);
|
|
return (e == null || tooHigh(e.key)) ? null : e;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absFloor(KEY_TYPE key) {
|
|
if (tooHigh(key)) return absHighest();
|
|
Node KEY_VALUE_GENERIC_TYPE e = map.findFloorNode(key);
|
|
return (e == null || tooLow(e.key)) ? null : e;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absLower(KEY_TYPE key) {
|
|
if (tooHigh(key)) return absHighest();
|
|
Node KEY_VALUE_GENERIC_TYPE e = map.findLowerNode(key);
|
|
return (e == null || tooLow(e.key)) ? null : e;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE absHighFence() { return (toEnd ? null : (hiInclusive ? map.findHigherNode(hi) : map.findCeilingNode(hi))); }
|
|
protected Node KEY_VALUE_GENERIC_TYPE absLowFence() { return (fromStart ? null : (loInclusive ? map.findLowerNode(lo) : map.findFloorNode(lo))); }
|
|
|
|
@Override
|
|
public COMPARATOR KEY_GENERIC_TYPE comparator() { return map.comparator(); }
|
|
|
|
@Override
|
|
public KEY_TYPE POLL_FIRST_ENTRY_KEY() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
|
if(entry != null) {
|
|
KEY_TYPE result = entry.key;
|
|
map.removeNode(entry);
|
|
return result;
|
|
}
|
|
return getDefaultMinValue();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE POLL_LAST_ENTRY_KEY() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
|
if(entry != null) {
|
|
KEY_TYPE result = entry.key;
|
|
map.removeNode(entry);
|
|
return result;
|
|
}
|
|
return getDefaultMaxValue();
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE FIRST_ENTRY_VALUE() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
|
if(entry == null) throw new NoSuchElementException();
|
|
return entry.value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE LAST_ENTRY_VALUE() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
|
if(entry == null) throw new NoSuchElementException();
|
|
return entry.value;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE FIRST_ENTRY_KEY() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
|
if(entry == null) throw new NoSuchElementException();
|
|
return entry.key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE LAST_ENTRY_KEY() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
|
if(entry == null) throw new NoSuchElementException();
|
|
return entry.key;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
|
|
if (!inRange(key)) throw new IllegalArgumentException("key out of range");
|
|
return map.put(key, value);
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE putIfAbsent(KEY_TYPE key, VALUE_TYPE value) {
|
|
if (!inRange(key)) throw new IllegalArgumentException("key out of range");
|
|
return map.putIfAbsent(key, value);
|
|
}
|
|
|
|
#if VALUE_PRIMITIVES
|
|
@Override
|
|
public VALUE_TYPE addTo(KEY_TYPE key, VALUE_TYPE value) {
|
|
if(!inRange(key)) throw new IllegalArgumentException("key out of range");
|
|
return map.addTo(key, value);
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE subFrom(KEY_TYPE key, VALUE_TYPE value) {
|
|
if(!inRange(key)) throw new IllegalArgumentException("key out of range");
|
|
return map.subFrom(key, value);
|
|
}
|
|
|
|
#endif
|
|
#if TYPE_OBJECT
|
|
@Override
|
|
public boolean containsKey(Object key) { return inRange((CLASS_TYPE)key) && map.containsKey(key); }
|
|
#else
|
|
@Override
|
|
public boolean containsKey(KEY_TYPE key) { return inRange(key) && map.containsKey(key); }
|
|
|
|
#endif
|
|
@Override
|
|
public VALUE_TYPE COMPUTE_IF_PRESENT(KEY_TYPE key, UNARY_OPERATOR KEY_VALUE_GENERIC_TYPE mappingFunction) {
|
|
Objects.requireNonNull(mappingFunction);
|
|
#if TYPE_OBJECT
|
|
map.validate(key);
|
|
#endif
|
|
if(!inRange(key)) return getDefaultReturnValue();
|
|
Node KEY_VALUE_GENERIC_TYPE entry = map.findNode(key);
|
|
#if VALUE_OBJECT
|
|
if(entry == null || VALUE_EQUALS(entry.value, getDefaultReturnValue())) return getDefaultReturnValue();
|
|
VALUE_TYPE newValue = mappingFunction.apply(key, entry.value);
|
|
if(VALUE_EQUALS(newValue, getDefaultReturnValue())) {
|
|
map.removeNode(entry);
|
|
return newValue;
|
|
}
|
|
entry.value = newValue;
|
|
return newValue;
|
|
#else
|
|
if(entry == null) return getDefaultReturnValue();
|
|
entry.value = mappingFunction.apply(key, entry.value);
|
|
return entry.value;
|
|
#endif
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE REMOVE_VALUE(KEY_TYPE key) {
|
|
return inRange(key) ? map.REMOVE_VALUE(key) : getDefaultReturnValue();
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE REMOVE_VALUEOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
|
|
return inRange(key) ? map.REMOVE_VALUEOrDefault(key, defaultValue) : defaultValue;
|
|
}
|
|
|
|
#if TYPE_OBJECT && VALUE_OBJECT
|
|
@Override
|
|
public boolean remove(Object key, Object value) {
|
|
return inRange((CLASS_TYPE)key) && map.remove(key, value);
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public boolean remove(KEY_TYPE key, VALUE_TYPE value) {
|
|
return inRange(key) && map.remove(key, value);
|
|
}
|
|
|
|
#endif
|
|
|
|
@Override
|
|
public VALUE_TYPE GET_VALUE(KEY_TYPE key) {
|
|
return inRange(key) ? map.GET_VALUE(key) : getDefaultReturnValue();
|
|
}
|
|
|
|
#if TYPE_OBJECT && VALUE_OBJECT
|
|
@Override
|
|
public VALUE_TYPE getOrDefault(Object key, VALUE_TYPE defaultValue) {
|
|
return inRange((CLASS_TYPE)key) ? map.getOrDefault(key, defaultValue) : getDefaultReturnValue();
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public VALUE_TYPE getOrDefault(KEY_TYPE key, VALUE_TYPE defaultValue) {
|
|
return inRange(key) ? map.getOrDefault(key, defaultValue) : getDefaultReturnValue();
|
|
}
|
|
|
|
#endif
|
|
|
|
@Override
|
|
public KEY_TYPE lowerKey(KEY_TYPE key) { return lowKeyOrNull(subLower(key)); }
|
|
@Override
|
|
public KEY_TYPE floorKey(KEY_TYPE key) { return lowKeyOrNull(subFloor(key)); }
|
|
@Override
|
|
public KEY_TYPE ceilingKey(KEY_TYPE key) { return highKeyOrNull(subCeiling(key)); }
|
|
@Override
|
|
public KEY_TYPE higherKey(KEY_TYPE key) { return highKeyOrNull(subHigher(key)); }
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE lowerEntry(KEY_TYPE key) { return subLower(key); }
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE floorEntry(KEY_TYPE key) { return subFloor(key); }
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE ceilingEntry(KEY_TYPE key) { return subCeiling(key); }
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE higherEntry(KEY_TYPE key) { return subHigher(key); }
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
if(fromStart && toEnd) return map.isEmpty();
|
|
Node KEY_VALUE_GENERIC_TYPE n = absLowest();
|
|
return n == null || tooHigh(n.key);
|
|
}
|
|
|
|
@Override
|
|
public int size() { return fromStart && toEnd ? map.size() : entrySet().size(); }
|
|
|
|
@Override
|
|
public NAVIGABLE_MAP KEY_VALUE_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE firstEntry() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
|
return entry == null ? null : entry.export();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE lastEntry() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
|
return entry == null ? null : entry.export();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollFirstEntry() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subLowest();
|
|
if(entry != null) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE result = entry.export();
|
|
map.removeNode(entry);
|
|
return result;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE pollLastEntry() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = subHighest();
|
|
if(entry != null) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE result = entry.export();
|
|
map.removeNode(entry);
|
|
return result;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
abstract class SubEntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
|
|
@Override
|
|
public int size() {
|
|
if (fromStart && toEnd) return map.size();
|
|
int size = 0;
|
|
for(ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iter = iterator();iter.hasNext();iter.next(),size++);
|
|
return size;
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
Node KEY_VALUE_GENERIC_TYPE n = absLowest();
|
|
return n == null || tooHigh(n.key);
|
|
}
|
|
|
|
@Override
|
|
public boolean contains(Object o) {
|
|
if (!(o instanceof Map.Entry)) return false;
|
|
if(o instanceof MAP.Entry)
|
|
{
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE) o;
|
|
#if TYPE_OBJECT
|
|
if(entry.ENTRY_KEY() == null && isNullComparator()) return false;
|
|
#endif
|
|
KEY_TYPE key = entry.ENTRY_KEY();
|
|
if (!inRange(key)) return false;
|
|
Node KEY_VALUE_GENERIC_TYPE node = map.findNode(key);
|
|
return node != null && VALUE_EQUALS(entry.ENTRY_VALUE(), node.ENTRY_VALUE());
|
|
}
|
|
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
|
|
if(entry.getKey() == null && isNullComparator()) return false;
|
|
CLASS_TYPE key = (CLASS_TYPE)entry.getKey();
|
|
if (!inRange(key)) return false;
|
|
Node KEY_VALUE_GENERIC_TYPE node = map.findNode(key);
|
|
return node != null && Objects.equals(entry.getValue(), VALUE_TO_OBJ(node.ENTRY_VALUE()));
|
|
}
|
|
|
|
@Override
|
|
public boolean remove(Object o) {
|
|
if (!(o instanceof Map.Entry)) return false;
|
|
if(o instanceof MAP.Entry)
|
|
{
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE) o;
|
|
KEY_TYPE key = entry.ENTRY_KEY();
|
|
if (!inRange(key)) return false;
|
|
Node KEY_VALUE_GENERIC_TYPE node = map.findNode(key);
|
|
if (node != null && VALUE_EQUALS(node.ENTRY_VALUE(), entry.ENTRY_VALUE())) {
|
|
map.removeNode(node);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
|
|
CLASS_TYPE key = (CLASS_TYPE)entry.getKey();
|
|
if (!inRange(key)) return false;
|
|
Node KEY_VALUE_GENERIC_TYPE node = map.findNode(key);
|
|
if (node != null && Objects.equals(node.getValue(), entry.getValue())) {
|
|
map.removeNode(node);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
action.accept(new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
|
|
@Override
|
|
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
|
Objects.requireNonNull(action);
|
|
int index = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
action.accept(index++, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
|
|
@Override
|
|
public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
action.accept(input, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return false;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return true;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return true;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(!filter.test(subEntry)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public <E> E reduce(E identity, BiFunction<E, MAP.Entry KEY_VALUE_GENERIC_TYPE, E> operator) {
|
|
Objects.requireNonNull(operator);
|
|
E state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
|
|
Objects.requireNonNull(operator);
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
|
|
boolean empty = true;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
if(empty) {
|
|
empty = false;
|
|
state = new BasicEntryKV_BRACES(entry.key, entry.value);
|
|
continue;
|
|
}
|
|
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return null;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) return subEntry;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return 0;
|
|
int result = 0;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) result++;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
final class SubMapValues extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE {
|
|
@Override
|
|
public boolean add(VALUE_TYPE o) { throw new UnsupportedOperationException(); }
|
|
|
|
#if VALUE_OBJECT
|
|
@Override
|
|
public boolean contains(Object e) {
|
|
return containsValue(e);
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public boolean contains(VALUE_TYPE e) {
|
|
return containsValue(e);
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() { return valueIterator(); }
|
|
|
|
@Override
|
|
public int size() {
|
|
return NavigableSubMap.this.size();
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
NavigableSubMap.this.clear();
|
|
}
|
|
|
|
@Override
|
|
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
action.accept(entry.value);
|
|
}
|
|
|
|
@Override
|
|
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
int index = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
action.accept(index++, entry.value);
|
|
}
|
|
|
|
@Override
|
|
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
action.accept(input, entry.value);
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
if(filter.test(entry.value)) return true;
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
if(filter.test(entry.value)) return false;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
if(!filter.test(entry.value)) return false;
|
|
return true;
|
|
}
|
|
|
|
#if !VALUE_OBJECT
|
|
@Override
|
|
public VALUE_TYPE reduce(VALUE_TYPE identity, VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
|
|
Objects.requireNonNull(operator);
|
|
VALUE_TYPE state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
state = operator.APPLY_VALUE(state, entry.value);
|
|
return state;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public <VALUE_SPECIAL_TYPE> VALUE_SPECIAL_TYPE reduce(VALUE_SPECIAL_TYPE identity, BiFunction<VALUE_SPECIAL_TYPE, VALUE_TYPE, VALUE_SPECIAL_TYPE> operator) {
|
|
Objects.requireNonNull(operator);
|
|
VALUE_SPECIAL_TYPE state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
state = operator.apply(state, entry.value);
|
|
return state;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
|
|
Objects.requireNonNull(operator);
|
|
VALUE_TYPE state = EMPTY_VALUE;
|
|
boolean empty = true;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry)) {
|
|
if(empty) {
|
|
empty = false;
|
|
state = entry.value;
|
|
continue;
|
|
}
|
|
state = operator.APPLY_VALUE(state, entry.value);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
if(filter.test(entry.value)) return entry.value;
|
|
return EMPTY_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public int count(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
int result = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = subLowest(), last = subHighest();entry != null && (last == null || last != previous(entry));entry = next(entry))
|
|
if(filter.test(entry.value)) result++;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
class DecsendingSubEntryIterator extends SubMapEntryIterator implements ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE>
|
|
{
|
|
public DecsendingSubEntryIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence) {
|
|
super(first, forwardFence, backwardFence, false);
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE moveNext(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.previous();
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE movePrevious(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.next();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry();
|
|
}
|
|
}
|
|
|
|
class AcsendingSubEntryIterator extends SubMapEntryIterator implements ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE>
|
|
{
|
|
public AcsendingSubEntryIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence) {
|
|
super(first, forwardFence, backwardFence, true);
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry();
|
|
}
|
|
}
|
|
|
|
class DecsendingSubKeyIterator extends SubMapEntryIterator implements BI_ITERATOR KEY_GENERIC_TYPE
|
|
{
|
|
public DecsendingSubKeyIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence) {
|
|
super(first, forwardFence, backwardFence, false);
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE moveNext(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.previous();
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE movePrevious(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.next();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().key;
|
|
}
|
|
}
|
|
|
|
class AcsendingSubKeyIterator extends SubMapEntryIterator implements BI_ITERATOR KEY_GENERIC_TYPE
|
|
{
|
|
public AcsendingSubKeyIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence) {
|
|
super(first, forwardFence, backwardFence, true);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().key;
|
|
}
|
|
}
|
|
|
|
class AcsendingSubValueIterator extends SubMapEntryIterator implements VALUE_BI_ITERATOR VALUE_GENERIC_TYPE
|
|
{
|
|
public AcsendingSubValueIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence) {
|
|
super(first, forwardFence, backwardFence, true);
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE VALUE_PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE VALUE_NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().value;
|
|
}
|
|
}
|
|
|
|
class DecsendingSubValueIterator extends SubMapEntryIterator implements VALUE_BI_ITERATOR VALUE_GENERIC_TYPE
|
|
{
|
|
public DecsendingSubValueIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence) {
|
|
super(first, forwardFence, backwardFence, false);
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE moveNext(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.previous();
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE movePrevious(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.next();
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE VALUE_PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE VALUE_NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().value;
|
|
}
|
|
}
|
|
|
|
abstract class SubMapEntryIterator
|
|
{
|
|
final boolean isForward;
|
|
boolean wasForward;
|
|
Node KEY_VALUE_GENERIC_TYPE lastReturned;
|
|
Node KEY_VALUE_GENERIC_TYPE next;
|
|
Node KEY_VALUE_GENERIC_TYPE previous;
|
|
boolean unboundForwardFence;
|
|
boolean unboundBackwardFence;
|
|
KEY_TYPE forwardFence;
|
|
KEY_TYPE backwardFence;
|
|
|
|
public SubMapEntryIterator(Node KEY_VALUE_GENERIC_TYPE first, Node KEY_VALUE_GENERIC_TYPE forwardFence, Node KEY_VALUE_GENERIC_TYPE backwardFence, boolean isForward) {
|
|
next = first;
|
|
previous = first == null ? null : movePrevious(first);
|
|
this.forwardFence = forwardFence == null ? EMPTY_KEY_VALUE : forwardFence.key;
|
|
this.backwardFence = backwardFence == null ? EMPTY_KEY_VALUE : backwardFence.key;
|
|
unboundForwardFence = forwardFence == null;
|
|
unboundBackwardFence = backwardFence == null;
|
|
this.isForward = isForward;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE moveNext(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.next();
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE movePrevious(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.previous();
|
|
}
|
|
|
|
public boolean hasNext() {
|
|
return next != null && (unboundForwardFence || next.key != forwardFence);
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE nextEntry() {
|
|
lastReturned = next;
|
|
previous = next;
|
|
Node KEY_VALUE_GENERIC_TYPE result = next;
|
|
next = moveNext(next);
|
|
wasForward = isForward;
|
|
return result;
|
|
}
|
|
|
|
public boolean hasPrevious() {
|
|
return previous != null && (unboundBackwardFence || previous.key != backwardFence);
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE previousEntry() {
|
|
lastReturned = previous;
|
|
next = previous;
|
|
Node KEY_VALUE_GENERIC_TYPE result = previous;
|
|
previous = movePrevious(previous);
|
|
wasForward = !isForward;
|
|
return result;
|
|
}
|
|
|
|
public void remove() {
|
|
if(lastReturned == null) throw new IllegalStateException();
|
|
if(next == lastReturned) next = moveNext(next);
|
|
if(previous == lastReturned) previous = movePrevious(previous);
|
|
if(wasForward && lastReturned.needsSuccessor()) next = lastReturned;
|
|
map.removeNode(lastReturned);
|
|
lastReturned = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
class Values extends VALUE_ABSTRACT_COLLECTION VALUE_GENERIC_TYPE
|
|
{
|
|
@Override
|
|
public VALUE_ITERATOR VALUE_GENERIC_TYPE iterator() {
|
|
return new AscendingValueIterator(first);
|
|
}
|
|
|
|
@Override
|
|
public boolean add(VALUE_TYPE e) { throw new UnsupportedOperationException(); }
|
|
|
|
@Override
|
|
public void clear() {
|
|
RB_TREE_MAP.this.clear();
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return RB_TREE_MAP.this.size;
|
|
}
|
|
|
|
#if VALUE_OBJECT
|
|
@Override
|
|
public boolean contains(Object e) {
|
|
return containsValue(e);
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public boolean contains(VALUE_TYPE e) {
|
|
return containsValue(e);
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public boolean remove(Object o) {
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first; entry != null; entry = entry.next()) {
|
|
if(Objects.equals(entry.getValue(), o)) {
|
|
removeNode(entry);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void forEach(VALUE_CONSUMER VALUE_SUPER_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(entry.value);
|
|
}
|
|
|
|
@Override
|
|
public void forEachIndexed(VALUE_BI_FROM_INT_CONSUMER VALUE_GENERIC_TYPE action) {
|
|
Objects.requireNonNull(action);
|
|
int index = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(index++, entry.value);
|
|
}
|
|
|
|
@Override
|
|
public <E> void forEach(E input, VALUE_BI_FROM_OBJECT_CONSUMER VSV_GENERIC_TYPE<E> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(input, entry.value);
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAny(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
if(filter.test(entry.value)) return true;
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesNone(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
if(filter.test(entry.value)) return false;
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAll(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
if(!filter.test(entry.value)) return false;
|
|
return true;
|
|
}
|
|
|
|
#if !VALUE_OBJECT
|
|
@Override
|
|
public VALUE_TYPE reduce(VALUE_TYPE identity, VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
|
|
Objects.requireNonNull(operator);
|
|
VALUE_TYPE state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
state = operator.APPLY_VALUE(state, entry.value);
|
|
return state;
|
|
}
|
|
|
|
#else
|
|
@Override
|
|
public <VALUE_SPECIAL_TYPE> VALUE_SPECIAL_TYPE reduce(VALUE_SPECIAL_TYPE identity, BiFunction<VALUE_SPECIAL_TYPE, VALUE_TYPE, VALUE_SPECIAL_TYPE> operator) {
|
|
Objects.requireNonNull(operator);
|
|
VALUE_SPECIAL_TYPE state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
state = operator.apply(state, entry.value);
|
|
return state;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public VALUE_TYPE reduce(VALUE_SINGLE_UNARY_OPERATOR VALUE_VALUE_GENERIC_TYPE operator) {
|
|
Objects.requireNonNull(operator);
|
|
VALUE_TYPE state = EMPTY_VALUE;
|
|
boolean empty = true;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
if(empty) {
|
|
empty = false;
|
|
state = entry.value;
|
|
continue;
|
|
}
|
|
state = operator.APPLY_VALUE(state, entry.value);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE findFirst(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
if(filter.test(entry.value)) return entry.value;
|
|
return EMPTY_VALUE;
|
|
}
|
|
|
|
@Override
|
|
public int count(VALUE_PREDICATE VALUE_GENERIC_TYPE filter) {
|
|
Objects.requireNonNull(filter);
|
|
int result = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
if(filter.test(entry.value)) result++;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
class EntrySet extends AbstractObjectSet<MAP.Entry KEY_VALUE_GENERIC_TYPE> {
|
|
|
|
@Override
|
|
public ObjectIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE> iterator() {
|
|
return new AscendingMapEntryIterator(first);
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
RB_TREE_MAP.this.clear();
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return RB_TREE_MAP.this.size;
|
|
}
|
|
|
|
@Override
|
|
public boolean contains(Object o) {
|
|
if (!(o instanceof Map.Entry)) return false;
|
|
if(o instanceof MAP.Entry)
|
|
{
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE) o;
|
|
#if TYPE_OBJECT
|
|
if(entry.getKey() == null && comparator() == null) return false;
|
|
#endif
|
|
KEY_TYPE key = entry.ENTRY_KEY();
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode(key);
|
|
return node != null && VALUE_EQUALS(entry.ENTRY_VALUE(), node.ENTRY_VALUE());
|
|
}
|
|
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
|
|
if(entry.getKey() == null && comparator() == null) return false;
|
|
#if !TYPE_OBJECT
|
|
if(!(entry.getKey() instanceof CLASS_TYPE)) return false;
|
|
#endif
|
|
CLASS_TYPE key = (CLASS_TYPE)entry.getKey();
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode(key);
|
|
return node != null && Objects.equals(entry.getValue(), VALUE_TO_OBJ(node.ENTRY_VALUE()));
|
|
}
|
|
|
|
@Override
|
|
public boolean remove(Object o) {
|
|
if (!(o instanceof Map.Entry)) return false;
|
|
if(o instanceof MAP.Entry)
|
|
{
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE) o;
|
|
KEY_TYPE key = entry.ENTRY_KEY();
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode(key);
|
|
if (node != null && VALUE_EQUALS(entry.ENTRY_VALUE(), node.ENTRY_VALUE())) {
|
|
removeNode(node);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
|
|
CLASS_TYPE key = (CLASS_TYPE)entry.getKey();
|
|
Node KEY_VALUE_GENERIC_TYPE node = findNode(key);
|
|
if (node != null && Objects.equals(entry.getValue(), VALUE_TO_OBJ(node.ENTRY_VALUE()))) {
|
|
removeNode(node);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void forEach(Consumer<? super MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
|
|
@Override
|
|
public void forEachIndexed(IntObjectConsumer<MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
|
Objects.requireNonNull(action);
|
|
int index = 0;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(index++, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
|
|
@Override
|
|
public <E> void forEach(E input, ObjectObjectConsumer<E, MAP.Entry KEY_VALUE_GENERIC_TYPE> action) {
|
|
Objects.requireNonNull(action);
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next())
|
|
action.accept(input, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAny(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return false;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesNone(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return true;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean matchesAll(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return true;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(!filter.test(subEntry)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public <E> E reduce(E identity, BiFunction<E, MAP.Entry KEY_VALUE_GENERIC_TYPE, E> operator) {
|
|
Objects.requireNonNull(operator);
|
|
E state = identity;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE reduce(ObjectObjectUnaryOperator<MAP.Entry KEY_VALUE_GENERIC_TYPE, MAP.Entry KEY_VALUE_GENERIC_TYPE> operator) {
|
|
Objects.requireNonNull(operator);
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE state = null;
|
|
boolean empty = true;
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
if(empty) {
|
|
empty = false;
|
|
state = new BasicEntryKV_BRACES(entry.key, entry.value);
|
|
continue;
|
|
}
|
|
state = operator.apply(state, new BasicEntryKV_BRACES(entry.key, entry.value));
|
|
}
|
|
return state;
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE findFirst(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return null;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) return subEntry;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int count(Predicate<MAP.Entry KEY_VALUE_GENERIC_TYPE> filter) {
|
|
Objects.requireNonNull(filter);
|
|
if(size() <= 0) return 0;
|
|
int result = 0;
|
|
BasicEntry KEY_VALUE_GENERIC_TYPE subEntry = new BasicEntryKV_BRACES();
|
|
for(Node KEY_VALUE_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) {
|
|
subEntry.set(entry.key, entry.value);
|
|
if(filter.test(subEntry)) result++;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
class DescendingKeyIterator extends MapEntryIterator implements BI_ITERATOR KEY_GENERIC_TYPE
|
|
{
|
|
public DescendingKeyIterator(Node KEY_VALUE_GENERIC_TYPE first) {
|
|
super(first, false);
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE moveNext(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.previous();
|
|
}
|
|
|
|
@Override
|
|
protected Node KEY_VALUE_GENERIC_TYPE movePrevious(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.next();
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().key;
|
|
}
|
|
}
|
|
|
|
class AscendingMapEntryIterator extends MapEntryIterator implements ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC_TYPE>
|
|
{
|
|
public AscendingMapEntryIterator(Node KEY_VALUE_GENERIC_TYPE first)
|
|
{
|
|
super(first, true);
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE previous() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry();
|
|
}
|
|
|
|
@Override
|
|
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry();
|
|
}
|
|
}
|
|
|
|
class AscendingValueIterator extends MapEntryIterator implements VALUE_BI_ITERATOR VALUE_GENERIC_TYPE
|
|
{
|
|
public AscendingValueIterator(Node KEY_VALUE_GENERIC_TYPE first) {
|
|
super(first, true);
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE VALUE_PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE VALUE_NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().value;
|
|
}
|
|
}
|
|
|
|
class AscendingKeyIterator extends MapEntryIterator implements BI_ITERATOR KEY_GENERIC_TYPE
|
|
{
|
|
public AscendingKeyIterator(Node KEY_VALUE_GENERIC_TYPE first) {
|
|
super(first, true);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE PREVIOUS() {
|
|
if(!hasPrevious()) throw new NoSuchElementException();
|
|
return previousEntry().key;
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE NEXT() {
|
|
if(!hasNext()) throw new NoSuchElementException();
|
|
return nextEntry().key;
|
|
}
|
|
}
|
|
|
|
abstract class MapEntryIterator
|
|
{
|
|
final boolean isForward;
|
|
boolean wasMoved = false;
|
|
Node KEY_VALUE_GENERIC_TYPE lastReturned;
|
|
Node KEY_VALUE_GENERIC_TYPE next;
|
|
Node KEY_VALUE_GENERIC_TYPE previous;
|
|
|
|
public MapEntryIterator(Node KEY_VALUE_GENERIC_TYPE first, boolean isForward) {
|
|
next = first;
|
|
previous = first == null ? null : movePrevious(first);
|
|
this.isForward = isForward;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE moveNext(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.next();
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE movePrevious(Node KEY_VALUE_GENERIC_TYPE node) {
|
|
return node.previous();
|
|
}
|
|
|
|
public boolean hasNext() {
|
|
return next != null;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE nextEntry() {
|
|
lastReturned = next;
|
|
previous = next;
|
|
Node KEY_VALUE_GENERIC_TYPE result = next;
|
|
next = moveNext(next);
|
|
wasMoved = isForward;
|
|
return result;
|
|
}
|
|
|
|
public boolean hasPrevious() {
|
|
return previous != null;
|
|
}
|
|
|
|
protected Node KEY_VALUE_GENERIC_TYPE previousEntry() {
|
|
lastReturned = previous;
|
|
next = previous;
|
|
Node KEY_VALUE_GENERIC_TYPE result = previous;
|
|
previous = movePrevious(previous);
|
|
wasMoved = !isForward;
|
|
return result;
|
|
}
|
|
|
|
public void remove() {
|
|
if(lastReturned == null) throw new IllegalStateException();
|
|
if(next == lastReturned) next = moveNext(next);
|
|
if(previous == lastReturned) previous = movePrevious(previous);
|
|
if(wasMoved && lastReturned.needsSuccessor()) next = lastReturned;
|
|
removeNode(lastReturned);
|
|
lastReturned = null;
|
|
}
|
|
}
|
|
|
|
private static final class Node KEY_VALUE_GENERIC_TYPE implements MAP.Entry KEY_VALUE_GENERIC_TYPE
|
|
{
|
|
static final int BLACK = 1;
|
|
|
|
KEY_TYPE key;
|
|
VALUE_TYPE value;
|
|
int state;
|
|
Node KEY_VALUE_GENERIC_TYPE parent;
|
|
Node KEY_VALUE_GENERIC_TYPE left;
|
|
Node KEY_VALUE_GENERIC_TYPE right;
|
|
|
|
Node(KEY_TYPE key, VALUE_TYPE value, Node KEY_VALUE_GENERIC_TYPE parent) {
|
|
this.key = key;
|
|
this.value = value;
|
|
this.parent = parent;
|
|
}
|
|
|
|
Node KEY_VALUE_GENERIC_TYPE copy() {
|
|
Node KEY_VALUE_GENERIC_TYPE entry = new NodeKV_BRACES(key, value, null);
|
|
entry.state = state;
|
|
if(left != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE newLeft = left.copy();
|
|
entry.left = newLeft;
|
|
newLeft.parent = entry;
|
|
}
|
|
if(right != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE newRight = right.copy();
|
|
entry.right = newRight;
|
|
newRight.parent = entry;
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
public BasicEntry KEY_VALUE_GENERIC_TYPE export() {
|
|
return new BasicEntryKV_BRACES(key, value);
|
|
}
|
|
|
|
@Override
|
|
public KEY_TYPE ENTRY_KEY() {
|
|
return key;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE ENTRY_VALUE() {
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public VALUE_TYPE setValue(VALUE_TYPE value) {
|
|
VALUE_TYPE oldValue = this.value;
|
|
this.value = value;
|
|
return oldValue;
|
|
}
|
|
|
|
#if VALUE_PRIMITIVES
|
|
VALUE_TYPE addTo(VALUE_TYPE value) {
|
|
VALUE_TYPE oldValue = this.value;
|
|
this.value += value;
|
|
return oldValue;
|
|
}
|
|
|
|
VALUE_TYPE subFrom(VALUE_TYPE value) {
|
|
VALUE_TYPE oldValue = this.value;
|
|
this.value -= value;
|
|
return oldValue;
|
|
}
|
|
|
|
#endif
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
if(obj instanceof Map.Entry) {
|
|
if(obj instanceof MAP.Entry) {
|
|
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)obj;
|
|
#if TYPE_OBJECT
|
|
if(entry.ENTRY_KEY() == null) return false;
|
|
#endif
|
|
return KEY_EQUALS(key, entry.ENTRY_KEY()) && VALUE_EQUALS(value, entry.ENTRY_VALUE());
|
|
}
|
|
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj;
|
|
Object otherKey = entry.getKey();
|
|
if(otherKey == null) return false;
|
|
Object otherValue = entry.getValue();
|
|
#if TYPE_OBJECT && VALUE_OBJECT
|
|
return KEY_EQUALS(key, otherKey) && VALUE_EQUALS(value, otherValue);
|
|
#else if TYPE_OBJECT
|
|
return otherValue instanceof CLASS_VALUE_TYPE && KEY_EQUALS(key, otherKey) && VALUE_EQUALS(value, CLASS_TO_VALUE(otherValue));
|
|
#else if VALUE_OBJECT
|
|
return otherKey instanceof CLASS_TYPE && KEY_EQUALS(key, CLASS_TO_KEY(otherKey)) && VALUE_EQUALS(value, otherValue);
|
|
#else
|
|
return otherKey instanceof CLASS_TYPE && otherValue instanceof CLASS_VALUE_TYPE && KEY_EQUALS(key, CLASS_TO_KEY(otherKey)) && VALUE_EQUALS(value, CLASS_TO_VALUE(otherValue));
|
|
#endif
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return KEY_TO_HASH(key) ^ VALUE_TO_HASH(value);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return KEY_TO_STRING(key) + "=" + VALUE_TO_STRING(value);
|
|
}
|
|
|
|
boolean isBlack() {
|
|
return (state & BLACK) != 0;
|
|
}
|
|
|
|
void setBlack(boolean value) {
|
|
if(value) state |= BLACK;
|
|
else state &= ~BLACK;
|
|
}
|
|
|
|
boolean needsSuccessor() { return left != null && right != null; }
|
|
|
|
boolean replace(Node KEY_VALUE_GENERIC_TYPE entry) {
|
|
if(entry != null) entry.parent = parent;
|
|
if(parent != null) {
|
|
if(parent.left == this) parent.left = entry;
|
|
else parent.right = entry;
|
|
}
|
|
return parent == null;
|
|
}
|
|
|
|
Node KEY_VALUE_GENERIC_TYPE next() {
|
|
if(right != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = right;
|
|
while(parent.left != null) parent = parent.left;
|
|
return parent;
|
|
}
|
|
Node KEY_VALUE_GENERIC_TYPE parent = this.parent;
|
|
Node KEY_VALUE_GENERIC_TYPE control = this;
|
|
while(parent != null && control == parent.right) {
|
|
control = parent;
|
|
parent = parent.parent;
|
|
}
|
|
return parent;
|
|
}
|
|
|
|
Node KEY_VALUE_GENERIC_TYPE previous() {
|
|
if(left != null) {
|
|
Node KEY_VALUE_GENERIC_TYPE parent = left;
|
|
while(parent.right != null) parent = parent.right;
|
|
return parent;
|
|
}
|
|
Node KEY_VALUE_GENERIC_TYPE parent = this.parent;
|
|
Node KEY_VALUE_GENERIC_TYPE control = this;
|
|
while(parent != null && control == parent.left) {
|
|
control = parent;
|
|
parent = parent.parent;
|
|
}
|
|
return parent;
|
|
}
|
|
}
|
|
} |