package speiger.src.collections.PACKAGE.sets; import java.util.Collection; #if TYPE_OBJECT import java.util.Comparator; import java.util.function.Consumer; #endif import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Objects; 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; #endif import speiger.src.collections.PACKAGE.functions.consumer.BI_OBJECT_CONSUMER; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; 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 FastUtil, * 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 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 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 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 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 } @Override public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { Objects.requireNonNull(action); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { action.accept(entry.key); } } @Override public void forEach(E input, BI_OBJECT_CONSUMER KEY_VALUE_SPECIAL_GENERIC_TYPE action) { Objects.requireNonNull(action); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) action.accept(entry.key, input); } @Override public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { if(filter.TEST_VALUE(entry.key)) return true; } return false; } @Override public boolean matchesNone(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { if(filter.TEST_VALUE(entry.key)) return false; } return true; } @Override public boolean matchesAll(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { if(!filter.TEST_VALUE(entry.key)) return false; } return true; } @Override public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { if(filter.TEST_VALUE(entry.key)) return entry.key; } return EMPTY_VALUE; } 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; } } }