Primitive-Collections/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template

1236 lines
36 KiB
Plaintext

package speiger.src.collections.PACKAGE.sets;
import java.util.Collection;
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import java.util.Iterator;
import java.util.NoSuchElementException;
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.collections.COLLECTION;
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.lists.LIST_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.utils.ITERATORS;
#endif
import speiger.src.collections.utils.SanityChecks;
/**
* A Simple Type Specific RB TreeSet 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)
*/
public class RB_TREE_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{
/** The center of the Tree */
protected transient Entry KEY_GENERIC_TYPE tree;
/** The Lowest possible Node */
protected transient Entry KEY_GENERIC_TYPE first;
/** The Highest possible Node */
protected transient Entry KEY_GENERIC_TYPE last;
/** The amount of elements stored in the Set */
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
/**
* Default Constructor
*/
public RB_TREE_SET() {
}
/**
* Constructor that allows to define the sorter
* @param comp the function that decides how the tree is sorted, can be null
*/
public RB_TREE_SET(COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp;
}
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
*/
public RB_TREE_SET(KEY_TYPE[] array) {
this(array, 0, array.length);
}
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param offset the starting index within the array
* @param length the amount of elements that are within the array
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public RB_TREE_SET(KEY_TYPE[] array, int offset, int length) {
SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]);
}
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
this(array, 0, array.length, comp);
}
/**
* Helper constructor that allow to create a set from an array
* @param array the elements that should be used
* @param offset the starting index within the array
* @param length the amount of elements that are within the array
* @param comp the sorter of the tree, can be null
* @throws IllegalStateException if offset and length causes to step outside of the arrays range
*/
public RB_TREE_SET(KEY_TYPE[] array, int offset, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp;
SanityChecks.checkArrayCapacity(array.length, offset, length);
for(int i = 0;i<length;i++) add(array[offset+i]);
}
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided SortedSet.
* @param sortedSet the set the elements should be added to the TreeSet
* @note this also includes the Comparator if present
*/
public RB_TREE_SET(SORTED_SET KEY_GENERIC_TYPE sortedSet) {
comparator = sortedSet.comparator();
addAll(sortedSet);
}
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
*/
@Primitive
public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection) {
addAll(collection);
}
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
* @param comp the sorter of the tree, can be null
*/
@Primitive
public RB_TREE_SET(Collection<? extends CLASS_TYPE> collection, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp;
addAll(collection);
}
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
*/
public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection) {
addAll(collection);
}
/**
* A Helper constructor that allows to create a Set with exactly the same values as the provided collection.
* @param collection the set the elements should be added to the TreeSet
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(COLLECTION KEY_GENERIC_TYPE collection, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp;
addAll(collection);
}
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public RB_TREE_SET(Iterator<CLASS_TYPE> iterator) {
#if !TYPE_OBJECT
this(ITERATORS.wrap(iterator));
#else
while(iterator.hasNext()) add(iterator.next());
#endif
}
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(Iterator<CLASS_TYPE> iterator, COMPARATOR KEY_GENERIC_TYPE comp) {
#if !TYPE_OBJECT
this(ITERATORS.wrap(iterator), comp);
#else
comparator = comp;
while(iterator.hasNext()) add(iterator.next());
#endif
}
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
*/
public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator) {
while(iterator.hasNext()) add(iterator.NEXT());
}
/**
* A Helper constructor that allows to create a set from a iterator of an unknown size
* @param iterator the elements that should be added to the set
* @param comp the sorter of the tree, can be null
*/
public RB_TREE_SET(ITERATOR KEY_GENERIC_TYPE iterator, COMPARATOR KEY_GENERIC_TYPE comp) {
comparator = comp;
while(iterator.hasNext()) add(iterator.NEXT());
}
#if !TYPE_OBJECT
@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 boolean add(KEY_TYPE o) {
if(tree == null) {
tree = first = last = new EntryBRACES(o, null);
size++;
return true;
}
int compare = 0;
Entry KEY_GENERIC_TYPE parent = tree;
while(true) {
if((compare = compare(o, parent.key)) == 0) return false;
if(compare < 0) {
if(parent.left == null) break;
parent = parent.left;
}
else if(compare > 0) {
if(parent.right == null) break;
parent = parent.right;
}
}
Entry KEY_GENERIC_TYPE adding = new EntryBRACES(o, 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 false;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE lower(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE node = findLowerNode(e);
#if TYPE_OBJECT
return node != null ? node.key : null;
#else
return node != null ? node.key : defaultMinNotFound;
#endif
}
@Override
public KEY_TYPE floor(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE node = findFloorNode(e);
#if TYPE_OBJECT
return node != null ? node.key : null;
#else
return node != null ? node.key : defaultMinNotFound;
#endif
}
@Override
public KEY_TYPE higher(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE node = findHigherNode(e);
#if TYPE_OBJECT
return node != null ? node.key : null;
#else
return node != null ? node.key : defaultMaxNotFound;
#endif
}
@Override
public KEY_TYPE ceiling(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE node = findCeilingNode(e);
#if TYPE_OBJECT
return node != null ? node.key : null;
#else
return node != null ? node.key : defaultMaxNotFound;
#endif
}
protected Entry KEY_GENERIC_TYPE findNode(KEY_TYPE o) {
Entry KEY_GENERIC_TYPE node = tree;
int compare;
while(node != null) {
if((compare = compare(o, node.key)) == 0) return node;
if(compare < 0) node = node.left;
else node = node.right;
}
return null;
}
protected Entry KEY_GENERIC_TYPE findLowerNode(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE entry = tree;
while(entry != null) {
if(compare(e, entry.key) > 0) {
if(entry.right != null) entry = entry.right;
else return entry;
}
else {
if(entry.left != null) entry = entry.left;
else {
Entry KEY_GENERIC_TYPE parent = entry.parent;
while(parent != null && parent.left == entry) {
entry = parent;
parent = parent.parent;
}
return parent;
}
}
}
return null;
}
protected Entry KEY_GENERIC_TYPE findFloorNode(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE entry = tree;
int compare;
while(entry != null) {
if((compare = compare(e, entry.key)) > 0) {
if(entry.right == null) break;
entry = entry.right;
continue;
}
else if(compare < 0) {
if(entry.left != null) entry = entry.left;
else {
Entry KEY_GENERIC_TYPE parent = entry.parent;
while(parent != null && parent.left == entry) {
entry = parent;
parent = parent.parent;
}
return parent;
}
continue;
}
break;
}
return entry;
}
protected Entry KEY_GENERIC_TYPE findCeilingNode(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE entry = tree;
int compare;
while(entry != null) {
if((compare = compare(e, entry.key)) < 0) {
if(entry.left == null) break;
entry = entry.left;
continue;
}
else if(compare > 0) {
if(entry.right != null) entry = entry.right;
else {
Entry KEY_GENERIC_TYPE parent = entry.parent;
while(parent != null && parent.right == entry) {
entry = parent;
parent = parent.parent;
}
return parent;
}
continue;
}
break;
}
return entry;
}
protected Entry KEY_GENERIC_TYPE findHigherNode(KEY_TYPE e) {
Entry KEY_GENERIC_TYPE entry = tree;
while(entry != null) {
if(compare(e, entry.key) < 0) {
if(entry.left != null) entry = entry.left;
else return entry;
}
else {
if(entry.right != null) entry = entry.right;
else {
Entry KEY_GENERIC_TYPE parent = entry.parent;
while(parent != null && parent.right == entry) {
entry = parent;
parent = parent.parent;
}
return parent;
}
}
}
return null;
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE e) {
return findNode(e) != null;
}
#endif
@Override
public boolean contains(Object e) {
return findNode(OBJ_TO_KEY(((CLASS_TYPE)e))) != null;
}
@Override
public KEY_TYPE FIRST_KEY() {
if(tree == null) throw new NoSuchElementException();
return first.key;
}
@Override
public KEY_TYPE LAST_KEY() {
if(tree == null) throw new NoSuchElementException();
return last.key;
}
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) {
if(tree == null) return false;
Entry KEY_GENERIC_TYPE entry = findNode(o);
if(entry != null) {
removeNode(entry);
return true;
}
return false;
}
#endif
@Override
public boolean remove(Object o) {
if(tree == null) return false;
Entry KEY_GENERIC_TYPE entry = findNode(OBJ_TO_KEY(((CLASS_TYPE)o)));
if(entry != null) {
removeNode(entry);
return true;
}
return false;
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
if(tree == null) throw new NoSuchElementException();
KEY_TYPE value = first.key;
removeNode(first);
return value;
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
if(tree == null) throw new NoSuchElementException();
KEY_TYPE value = last.key;
removeNode(last);
return value;
}
@Override
public int size() { return size; }
@Override
public void clear() {
size = 0;
first = null;
last = null;
tree = null;
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return new SetIterator(false); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
Entry KEY_GENERIC_TYPE entry = findNode(fromElement);
return entry == null ? null : new SetIterator(entry);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return new SetIterator(true); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) {
return new AscendingSubSetBRACES(this, false, fromElement, fromInclusive, false, toElement, toInclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) {
return new AscendingSubSetBRACES(this, true, EMPTY_KEY_VALUE, true, false, toElement, inclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) {
return new AscendingSubSetBRACES(this, false, fromElement, inclusive, true, EMPTY_KEY_VALUE, true);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() {
return new DescendingSubSetBRACES(this, true, EMPTY_KEY_VALUE, true, true, EMPTY_KEY_VALUE, true);
}
protected void removeNode(Entry KEY_GENERIC_TYPE entry) {
size--;
if(entry.needsSuccessor()) {
Entry KEY_GENERIC_TYPE successor = entry.next();
entry.key = successor.key;
entry = successor;
}
Entry KEY_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) {
Entry KEY_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 int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);}
protected static GENERIC_KEY_BRACES boolean isBlack(Entry KEY_GENERIC_TYPE p) { return p == null || p.isBlack(); }
protected static GENERIC_KEY_BRACES Entry KEY_GENERIC_TYPE parentOf(Entry KEY_GENERIC_TYPE p) { return (p == null ? null : p.parent); }
protected static GENERIC_KEY_BRACES void setBlack(Entry KEY_GENERIC_TYPE p, boolean c) { if(p != null) p.setBlack(c); }
protected static GENERIC_KEY_BRACES Entry KEY_GENERIC_TYPE leftOf(Entry KEY_GENERIC_TYPE p) { return p == null ? null : p.left; }
protected static GENERIC_KEY_BRACES Entry KEY_GENERIC_TYPE rightOf(Entry KEY_GENERIC_TYPE p) { return (p == null) ? null : p.right; }
/** From CLR */
protected void rotateLeft(Entry KEY_GENERIC_TYPE entry) {
if(entry != null) {
Entry KEY_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;
}
}
/** From CLR */
protected void rotateRight(Entry KEY_GENERIC_TYPE entry) {
if(entry != null) {
Entry KEY_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;
}
}
/** From CLR */
protected void fixAfterInsertion(Entry KEY_GENERIC_TYPE entry) {
entry.setBlack(false);
while(entry != null && entry != tree && !entry.parent.isBlack()) {
if(parentOf(entry) == leftOf(parentOf(parentOf(entry)))) {
Entry KEY_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 {
Entry KEY_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);
}
/** From CLR */
protected void fixAfterDeletion(Entry KEY_GENERIC_TYPE entry) {
while(entry != tree && isBlack(entry)) {
if(entry == leftOf(parentOf(entry))) {
Entry KEY_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 {
Entry KEY_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);
}
private static class AscendingSubSet KEY_GENERIC_TYPE extends SubSet KEY_GENERIC_TYPE
{
AscendingSubSet(RB_TREE_SET KEY_GENERIC_TYPE set, boolean fromStart, KEY_TYPE start, boolean loInclusive, boolean toEnd, KEY_TYPE end, boolean hiInclusive) {
super(set, fromStart, start, loInclusive, toEnd, end, hiInclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) {
if(!inRange(fromElement, fromInclusive)) throw new IllegalArgumentException("fromElement is not in Range");
if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement is not in Range");
return new AscendingSubSetBRACES(set, false, fromElement, fromInclusive, false, toElement, toInclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) {
if(!inRange(toElement, inclusive)) throw new IllegalArgumentException("toElement is not in Range");
return new AscendingSubSetBRACES(set, fromStart, start, loInclusive, false, toElement, inclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) {
if(!inRange(fromElement, inclusive)) throw new IllegalArgumentException("fromElement is not in Range");
return new AscendingSubSetBRACES(set, false, fromElement, inclusive, toEnd, end, hiInclusive);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return new SubSetIterator(findLowest()); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
Entry KEY_GENERIC_TYPE entry = set.findNode(fromElement);
return entry == null || !inClosedRange(fromElement) ? null : new SubSetIterator(entry);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return new SubSetIterator(findHighest()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() {
return new DescendingSubSetBRACES(set, fromStart, start, loInclusive, toEnd, end, hiInclusive);
}
}
private static class DescendingSubSet KEY_GENERIC_TYPE extends SubSet KEY_GENERIC_TYPE
{
COMPARATOR KEY_GENERIC_TYPE comparator;
DescendingSubSet(RB_TREE_SET KEY_GENERIC_TYPE set, boolean fromStart, KEY_TYPE start, boolean loInclusive, boolean toEnd, KEY_TYPE end, boolean hiInclusive) {
super(set, fromStart, start, loInclusive, toEnd, end, hiInclusive);
comparator = set.comparator();
if(comparator != null) comparator = comparator.reversed();
}
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) {
if(!inRange(fromElement, fromInclusive)) throw new IllegalArgumentException("fromElement is not in Range");
if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement is not in Range");
return new DescendingSubSetBRACES(set, false, toElement, toInclusive, false, fromElement, fromInclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) {
if(!inRange(toElement, inclusive)) throw new IllegalArgumentException("toElement is not in Range");
return new DescendingSubSetBRACES(set, false, toElement, inclusive, toEnd, end, hiInclusive);
}
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) {
if(!inRange(fromElement, inclusive)) throw new IllegalArgumentException("fromElement is not in Range");
return new DescendingSubSetBRACES(set, fromStart, start, loInclusive, false, fromElement, inclusive);
}
@Override
public KEY_TYPE FIRST_KEY() { return super.LAST_KEY(); }
@Override
public KEY_TYPE POLL_FIRST_KEY() { return super.POLL_LAST_KEY(); }
@Override
public KEY_TYPE LAST_KEY() { return super.FIRST_KEY(); }
@Override
public KEY_TYPE POLL_LAST_KEY() { return super.POLL_FIRST_KEY(); }
@Override
public KEY_TYPE lower(KEY_TYPE e) { return super.higher(e); }
@Override
public KEY_TYPE floor(KEY_TYPE e) { return super.ceiling(e); }
@Override
public KEY_TYPE ceiling(KEY_TYPE e) { return super.floor(e); }
@Override
public KEY_TYPE higher(KEY_TYPE e) { return super.lower(e); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return new DescendingSubIterator(findHighest()); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
Entry KEY_GENERIC_TYPE entry = set.findNode(fromElement);
return entry == null || !inClosedRange(fromElement) ? null : new DescendingSubIterator(entry);
}
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return new DescendingSubIterator(findLowest()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() {
return new AscendingSubSetBRACES(set, fromStart, start, loInclusive, toEnd, end, hiInclusive);
}
private class DescendingSubIterator extends SubSetIterator
{
public DescendingSubIterator(Entry KEY_GENERIC_TYPE entry) {
super(entry);
}
@Override
protected void updateNext() {
next = current.previous();
if(!toEnd && next != null && bottomReached(next)) next = null;
}
@Override
protected void updatePrevious() {
previous = current.next();
if(!fromStart && previous != null && topReached(previous)) previous = null;
}
}
}
private static abstract class SubSet KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{
RB_TREE_SET KEY_GENERIC_TYPE set;
KEY_TYPE start;
KEY_TYPE end;
boolean fromStart;
boolean toEnd;
boolean loInclusive;
boolean hiInclusive;
SubSet(RB_TREE_SET KEY_GENERIC_TYPE set, boolean fromStart, KEY_TYPE start, boolean loInclusive, boolean toEnd, KEY_TYPE end, boolean hiInclusive) {
this.set = set;
this.start = start;
this.end = end;
this.fromStart = fromStart;
this.toEnd = toEnd;
this.loInclusive = loInclusive;
this.hiInclusive = hiInclusive;
}
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE value) { set.setDefaultMaxValue(value); }
@Override
public KEY_TYPE getDefaultMaxValue() { return set.getDefaultMaxValue(); }
@Override
public void setDefaultMinValue(KEY_TYPE value) { set.setDefaultMinValue(value); }
@Override
public KEY_TYPE getDefaultMinValue() { return set.getDefaultMinValue(); }
#else
public KEY_TYPE getDefaultMaxValue() { return null; }
public KEY_TYPE getDefaultMinValue() { return null; }
#endif
boolean tooLow(KEY_TYPE key) { return !fromStart && (loInclusive ? set.compare(key, start) < 0 : set.compare(key, start) <= 0); }
boolean tooHigh(KEY_TYPE key) { return !toEnd && (hiInclusive ? set.compare(key, end) > 0 : set.compare(key, end) >= 0); }
boolean inRange(KEY_TYPE key) { return !tooLow(key) && !tooHigh(key); }
boolean inClosedRange(KEY_TYPE key) { return (fromStart || set.compare(key, start) >= 0) && (toEnd || set.compare(end, key) >= 0); }
boolean inRange(KEY_TYPE key, boolean inclusive) { return inclusive ? inRange(key) : inClosedRange(key); }
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return set.comparator(); }
@Override
public abstract BI_ITERATOR KEY_GENERIC_TYPE iterator();
@Override
public KEY_TYPE FIRST_KEY() {
Entry KEY_GENERIC_TYPE entry = findLowest();
return entry == null ? getDefaultMaxValue() : entry.key;
}
protected Entry KEY_GENERIC_TYPE findLowest() {
if(fromStart) return set.first;
Entry KEY_GENERIC_TYPE entry = loInclusive ? set.findCeilingNode(start) : set.findHigherNode(start);
return entry == null || tooHigh(entry.key) ? null : entry;
}
@Override
public KEY_TYPE POLL_FIRST_KEY() {
if(fromStart) return set.POLL_FIRST_KEY();
Entry KEY_GENERIC_TYPE entry = loInclusive ? set.findCeilingNode(start) : set.findHigherNode(start);
if(entry != null && !tooHigh(entry.key)) {
KEY_TYPE value = entry.key;
set.removeNode(entry);
return value;
}
return getDefaultMaxValue();
}
@Override
public KEY_TYPE LAST_KEY() {
Entry KEY_GENERIC_TYPE entry = findHighest();
return entry == null ? getDefaultMinValue() : entry.key;
}
protected Entry KEY_GENERIC_TYPE findHighest() {
if(toEnd) return set.last;
Entry KEY_GENERIC_TYPE entry = hiInclusive ? set.findFloorNode(end) : set.findLowerNode(end);
return entry == null || tooLow(entry.key) ? null : entry;
}
@Override
public KEY_TYPE POLL_LAST_KEY() {
if(toEnd) return set.POLL_LAST_KEY();
Entry KEY_GENERIC_TYPE entry = hiInclusive ? set.findFloorNode(end) : set.findLowerNode(end);
if(entry != null && !tooLow(entry.key)) {
KEY_TYPE value = entry.key;
set.removeNode(entry);
return value;
}
return getDefaultMinValue();
}
@Override
public boolean add(KEY_TYPE o) {
if(!inRange(o)) throw new IllegalArgumentException("Key is out of range");
return set.add(o);
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE e) {
return inRange(e) && set.contains(e);
}
@Override
public boolean remove(KEY_TYPE o) {
return inRange(o) && set.remove(o);
}
#endif
@Override
public boolean contains(Object e) {
KEY_TYPE o = OBJ_TO_KEY(((CLASS_TYPE)e));
return inRange(o) && set.contains(o);
}
@Override
public boolean remove(Object e) {
KEY_TYPE o = OBJ_TO_KEY(((CLASS_TYPE)e));
return inRange(o) && set.remove(o);
}
@Override
public KEY_TYPE lower(KEY_TYPE e) {
if(tooHigh(e)) {
Entry KEY_GENERIC_TYPE entry = findHighest();
return entry == null ? getDefaultMinValue() : entry.key;
}
Entry KEY_GENERIC_TYPE entry = set.findLowerNode(e);
return entry == null || tooHigh(entry.key) ? getDefaultMaxValue() : entry.key;
}
@Override
public KEY_TYPE floor(KEY_TYPE e) {
if(tooHigh(e)) {
Entry KEY_GENERIC_TYPE entry = findHighest();
return entry == null ? getDefaultMinValue() : entry.key;
}
Entry KEY_GENERIC_TYPE entry = set.findFloorNode(e);
return entry == null || tooHigh(entry.key) ? getDefaultMaxValue() : entry.key;
}
@Override
public KEY_TYPE ceiling(KEY_TYPE e) {
if(tooLow(e)) {
Entry KEY_GENERIC_TYPE entry = findLowest();
return entry == null ? getDefaultMaxValue() : entry.key;
}
Entry KEY_GENERIC_TYPE entry = set.findCeilingNode(e);
return entry == null || tooLow(entry.key) ? getDefaultMinValue() : entry.key;
}
@Override
public KEY_TYPE higher(KEY_TYPE e) {
if(tooLow(e)) {
Entry KEY_GENERIC_TYPE entry = findLowest();
return entry == null ? getDefaultMaxValue() : entry.key;
}
Entry KEY_GENERIC_TYPE entry = set.findHigherNode(e);
return entry == null || tooLow(entry.key) ? getDefaultMinValue() : entry.key;
}
@Override
public int size() {
return fromStart && toEnd ? set.size() : iterator().skip(Integer.MAX_VALUE);
}
class SubSetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE
{
Entry KEY_GENERIC_TYPE previous;
Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE current;
int index = 0;
public SubSetIterator(Entry KEY_GENERIC_TYPE entry) {
next = entry;
previous = entry == null ? null : entry.previous();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public boolean hasPrevious() {
return previous != null;
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index - 1;
}
boolean topReached(Entry KEY_GENERIC_TYPE entry) {
return hiInclusive ? set.compare(entry.key, end) >= 0 : set.compare(entry.key, end) > 0;
}
boolean bottomReached(Entry KEY_GENERIC_TYPE entry) {
return loInclusive ? set.compare(entry.key, start) <= 0 : set.compare(entry.key, start) < 0;
}
protected void updateNext() {
next = current.next();
if(!toEnd && next != null && topReached(next)) next = null;
}
protected void updatePrevious() {
previous = current.previous();
if(!fromStart && previous != null && bottomReached(previous)) previous = null;
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = previous = next;
updateNext();
index++;
return current.key;
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous;
updatePrevious();
index--;
return current.key;
}
@Override
public void remove() {
if(current == null) throw new IllegalStateException();
if(current == previous) index--;
updateNext();
updatePrevious();
if(current.needsSuccessor()) next = current;
set.removeNode(current);
current = null;
}
@Override
public void set(KEY_TYPE e){ throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
}
}
private class SetIterator implements LIST_ITERATOR KEY_GENERIC_TYPE
{
Entry KEY_GENERIC_TYPE previous;
Entry KEY_GENERIC_TYPE next;
Entry KEY_GENERIC_TYPE current;
int index = 0;
public SetIterator(boolean descending) {
if(descending) previous = last;
else next = first;
}
public SetIterator(Entry KEY_GENERIC_TYPE entry) {
next = entry;
previous = entry.previous();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public boolean hasPrevious() {
return previous != null;
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index - 1;
}
protected void updateNext() {
next = current.next();
}
protected void updatePrevious() {
previous = current.previous();
}
@Override
public KEY_TYPE NEXT() {
if(!hasNext()) throw new NoSuchElementException();
current = previous = next;
updateNext();
index++;
return current.key;
}
@Override
public KEY_TYPE PREVIOUS() {
if(!hasPrevious()) throw new NoSuchElementException();
current = next = previous;
updatePrevious();
index--;
return current.key;
}
@Override
public void remove() {
if(current == null) throw new IllegalStateException();
if(current == previous) index--;
updateNext();
updatePrevious();
if(current.needsSuccessor()) next = current;
removeNode(current);
current = null;
}
@Override
public void set(KEY_TYPE e){ throw new UnsupportedOperationException(); }
@Override
public void add(KEY_TYPE e) { throw new UnsupportedOperationException(); }
}
private static final class Entry KEY_GENERIC_TYPE
{
static final int BLACK = 1;
KEY_TYPE key;
int state;
Entry KEY_GENERIC_TYPE parent;
Entry KEY_GENERIC_TYPE left;
Entry KEY_GENERIC_TYPE right;
Entry(KEY_TYPE key, Entry KEY_GENERIC_TYPE parent) {
this.key = key;
this.parent = parent;
}
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(Entry KEY_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;
}
Entry KEY_GENERIC_TYPE next() {
if(right != null) {
Entry KEY_GENERIC_TYPE parent = right;
while(parent.left != null) parent = parent.left;
return parent;
}
Entry KEY_GENERIC_TYPE parent = this.parent;
Entry KEY_GENERIC_TYPE control = this;
while(parent != null && control == parent.right) {
control = parent;
parent = parent.parent;
}
return parent;
}
Entry KEY_GENERIC_TYPE previous() {
if(left != null) {
Entry KEY_GENERIC_TYPE parent = left;
while(parent.right != null) parent = parent.right;
return parent;
}
Entry KEY_GENERIC_TYPE parent = this.parent;
Entry KEY_GENERIC_TYPE control = this;
while(parent != null && control == parent.left) {
control = parent;
parent = parent.parent;
}
return parent;
}
}
}