package speiger.src.collections.PACKAGE.sets; import java.util.Collection; import java.util.Collections; #if TYPE_OBJECT import java.util.Comparator; import java.util.function.Consumer; import java.util.function.BiFunction; #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.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; import speiger.src.collections.PACKAGE.functions.function.PREDICATE; import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; import speiger.src.collections.PACKAGE.collections.COLLECTION; import speiger.src.collections.PACKAGE.collections.ITERATOR; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.utils.ITERATORS; #endif import speiger.src.collections.utils.SanityChecks; /** * A Simple Type Specific AVL 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 AVL_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 AVL_TREE_SET() { } /** * Constructor that allows to define the sorter * @param comp the function that decides how the tree is sorted, can be null */ public AVL_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 AVL_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 AVL_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 AVL_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 AVL_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 AVL_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 AVL_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 AVL_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 AVL_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 AVL_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; } #else /** only used for primitives * @return null */ public CLASS_TYPE getDefaultMaxValue() { return null; } /** only used for primitives * @return null */ public CLASS_TYPE getDefaultMinValue() { return null; } #endif @Override public boolean add(KEY_TYPE o) { #if TYPE_OBJECT validate(o); #endif 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 true; } @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); return node != null ? node.key : getDefaultMinValue(); } @Override public KEY_TYPE floor(KEY_TYPE e) { Entry KEY_GENERIC_TYPE node = findFloorNode(e); return node != null ? node.key : getDefaultMinValue(); } @Override public KEY_TYPE higher(KEY_TYPE e) { Entry KEY_GENERIC_TYPE node = findHigherNode(e); return node != null ? node.key : getDefaultMaxValue(); } @Override public KEY_TYPE ceiling(KEY_TYPE e) { Entry KEY_GENERIC_TYPE node = findCeilingNode(e); return node != null ? node.key : getDefaultMaxValue(); } #if !TYPE_OBJECT @Override public CLASS_TYPE lower(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE node = findLowerNode(e); return node != null ? node.key : null; } @Override public CLASS_TYPE floor(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE node = findFloorNode(e); return node != null ? node.key : null; } @Override public CLASS_TYPE higher(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE node = findHigherNode(e); return node != null ? node.key : null; } @Override public CLASS_TYPE ceiling(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE node = findCeilingNode(e); return node != null ? node.key : null; } #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_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { Objects.requireNonNull(action); for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) action.accept(input, entry.key); } @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; } #if !TYPE_OBJECT @Override public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { Objects.requireNonNull(operator); KEY_TYPE state = identity; for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { state = operator.APPLY_VALUE(state, entry.key); } return state; } #else @Override public KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { Objects.requireNonNull(operator); KEY_SPECIAL_TYPE state = identity; for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { state = operator.APPLY_VALUE(state, entry.key); } return state; } #endif @Override public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { Objects.requireNonNull(operator); KEY_TYPE state = EMPTY_VALUE; boolean empty = true; for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { if(empty) { empty = false; state = entry.key; continue; } state = operator.APPLY_VALUE(state, entry.key); } return state; } @Override public int count(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); int result = 0; for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { if(filter.TEST_VALUE(entry.key)) result++; } return result; } 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 TYPE_OBJECT if(tree == null) return null; #else if(tree == null) return getDefaultMinValue(); #endif KEY_TYPE value = first.key; removeNode(first); return value; } @Override public KEY_TYPE POLL_LAST_KEY() { #if TYPE_OBJECT if(tree == null) return null; #else if(tree == null) return getDefaultMaxValue(); #endif 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; } public AVL_TREE_SET KEY_GENERIC_TYPE copy() { AVL_TREE_SET KEY_GENERIC_TYPE set = new AVL_TREE_SETBRACES(); set.size = size; if(tree != null) { set.tree = tree.copy(); Entry KEY_GENERIC_TYPE lastFound = null; for(Entry KEY_GENERIC_TYPE entry = tree;entry != null;entry = entry.left) lastFound = entry; set.first = lastFound; lastFound = null; for(Entry KEY_GENERIC_TYPE entry = tree;entry != null;entry = entry.right) lastFound = entry; set.last = lastFound; } return set; } @Override public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return new AscendingSetIterator(first); } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { Entry KEY_GENERIC_TYPE entry = findNode(fromElement); return entry == null ? null : new AscendingSetIterator(entry); } @Override public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return new DescendingSetIterator(last); } @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; } if(entry.previous() == null) first = entry.next(); if(entry.next() == null) last = entry.previous(); Entry KEY_GENERIC_TYPE replacement = entry.left != null ? entry.left : entry.right; if(replacement != null) { if(entry.replace(replacement)) tree = replacement; entry.left = entry.right = entry.parent = null; fixAfterDeletion(replacement); } else if(entry.parent == null) tree = first = last = null; else { fixAfterDeletion(entry); entry.replace(null); 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);} /** 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; entry.updateHeight(); right.updateHeight(); } } /** 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; entry.updateHeight(); left.updateHeight(); } } /** From CLR */ protected void fixAfterInsertion(Entry KEY_GENERIC_TYPE entry) { while(entry != null) { entry.updateHeight(); int balance = entry.getBalance(); if(balance > 1) { int compare = entry.left.getBalance(); if(compare > 0) rotateRight(entry); else if(compare < 0) { rotateLeft(entry.left); rotateRight(entry); } } else if(balance < -1) { int compare = entry.right.getBalance(); if(compare < 0) rotateLeft(entry); else if(compare > 0) { rotateRight(entry.right); rotateLeft(entry); } } entry = entry.parent; } } /** From CLR */ protected void fixAfterDeletion(Entry KEY_GENERIC_TYPE entry) { if(entry != null) { entry.updateHeight(); int balance = entry.getBalance(); if(balance > 1) { int subBalance = entry.left.getBalance(); if(subBalance >= 0) rotateRight(entry); else { rotateLeft(entry.left); rotateRight(entry); } } else if(balance < -1) { int subBalance = entry.right.getBalance(); if(subBalance <= 0) rotateLeft(entry); else { rotateRight(entry.right); rotateLeft(entry); } } entry = entry.parent; } } static class AscendingSubSet KEY_GENERIC_TYPE extends SubSet KEY_GENERIC_TYPE { public AscendingSubSet(AVL_TREE_SET KEY_GENERIC_TYPE set, boolean fromStart, KEY_TYPE lo, boolean loInclusive, boolean toEnd, KEY_TYPE hi, boolean hiInclusive) { super(set, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } @Override public COMPARATOR KEY_GENERIC_TYPE comparator() { return set.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 out of range"); if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement out of 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 out of range"); return new AscendingSubSetBRACES(set, fromStart, lo, 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 out of range"); return new AscendingSubSetBRACES(set, false, fromElement, inclusive, toEnd, hi, hiInclusive); } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return new AscendingSubSetIterator(absLowest(), absHighFence(), absLowFence()); } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new AscendingSubSetIterator(absLower(fromElement), absHighFence(), absLowFence()); } @Override public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return new DescendingSubSetIterator(absHighest(), absLowFence(), absHighFence()); } @Override public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { if(inverse == null) inverse = new DescendingSubSetBRACES(set, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); return inverse; } @Override protected Entry KEY_GENERIC_TYPE subLowest() { return absLowest(); } @Override protected Entry KEY_GENERIC_TYPE subHighest() { return absHighest(); } @Override protected Entry KEY_GENERIC_TYPE subCeiling(KEY_TYPE key) { return absCeiling(key); } @Override protected Entry KEY_GENERIC_TYPE subHigher(KEY_TYPE key) { return absHigher(key); } @Override protected Entry KEY_GENERIC_TYPE subFloor(KEY_TYPE key) { return absFloor(key); } @Override protected Entry KEY_GENERIC_TYPE subLower(KEY_TYPE key) { return absLower(key); } @Override protected Entry KEY_GENERIC_TYPE start() { return absLowest(); } @Override protected Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry) { return entry.next(); } } static class DescendingSubSet KEY_GENERIC_TYPE extends SubSet KEY_GENERIC_TYPE { COMPARATOR KEY_GENERIC_TYPE comparator; public DescendingSubSet(AVL_TREE_SET KEY_GENERIC_TYPE set, boolean fromStart, KEY_TYPE lo, boolean loInclusive, boolean toEnd, KEY_TYPE hi, boolean hiInclusive) { super(set, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); #if TYPE_OBJECT comparator = Collections.reverseOrder(set.comparator()); #else comparator = set.comparator() == null ? COMPARATOR.of(Collections.reverseOrder()) : set.comparator().reversed(); #endif } @Override public COMPARATOR KEY_GENERIC_TYPE comparator() { return comparator; } public KEY_TYPE getDefaultMaxValue() { return super.getDefaultMinValue(); } public KEY_TYPE getDefaultMinValue() { return super.getDefaultMaxValue(); } @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 out of range"); if(!inRange(toElement, toInclusive)) throw new IllegalArgumentException("toElement out of range"); return new DescendingSubSetBRACES(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 out of range"); return new DescendingSubSetBRACES(set, false, toElement, inclusive, toEnd, hi, hiInclusive); } @Override public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) { if(!inRange(fromElement, inclusive)) throw new IllegalArgumentException("fromElement out of range"); return new DescendingSubSetBRACES(set, fromStart, lo, loInclusive, false, fromElement, inclusive); } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return new DescendingSubSetIterator(absHighest(), absLowFence(), absHighFence()); } @Override public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return new AscendingSubSetIterator(absLowest(), absHighFence(), absLowFence()); } @Override public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { if(inverse == null) inverse = new AscendingSubSetBRACES(set, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); return inverse; } @Override public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return new DescendingSubSetIterator(absHigher(fromElement), absLowFence(), absHighFence()); } @Override protected Entry KEY_GENERIC_TYPE subLowest() { return absHighest(); } @Override protected Entry KEY_GENERIC_TYPE subHighest() { return absLowest(); } @Override protected Entry KEY_GENERIC_TYPE subCeiling(KEY_TYPE key) { return absFloor(key); } @Override protected Entry KEY_GENERIC_TYPE subHigher(KEY_TYPE key) { return absLower(key); } @Override protected Entry KEY_GENERIC_TYPE subFloor(KEY_TYPE key) { return absCeiling(key); } @Override protected Entry KEY_GENERIC_TYPE subLower(KEY_TYPE key) { return absHigher(key); } @Override protected Entry KEY_GENERIC_TYPE start() { return absHighest(); } @Override protected Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry) { return entry.previous(); } } static abstract class SubSet KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE { final AVL_TREE_SET KEY_GENERIC_TYPE set; final KEY_TYPE lo, hi; final boolean fromStart, toEnd; final boolean loInclusive, hiInclusive; NAVIGABLE_SET KEY_GENERIC_TYPE inverse; public SubSet(AVL_TREE_SET KEY_GENERIC_TYPE set, boolean fromStart, KEY_TYPE lo, boolean loInclusive, boolean toEnd, KEY_TYPE hi, boolean hiInclusive) { this.set = set; this.lo = lo; this.hi = hi; 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 @Override public abstract BI_ITERATOR KEY_GENERIC_TYPE iterator(); boolean tooLow(KEY_TYPE key) { if (!fromStart) { int c = set.compare(key, lo); if (c < 0 || (c == 0 && !loInclusive)) return true; } return false; } boolean tooHigh(KEY_TYPE key) { if (!toEnd) { int c = set.compare(key, hi); if (c > 0 || (c == 0 && !hiInclusive)) return true; } return false; } boolean inRange(KEY_TYPE key) { return !tooLow(key) && !tooHigh(key); } boolean inClosedRange(KEY_TYPE key) { return (fromStart || set.compare(key, lo) >= 0) && (toEnd || set.compare(hi, key) >= 0); } boolean inRange(KEY_TYPE key, boolean inclusive) { return inclusive ? inRange(key) : inClosedRange(key); } protected abstract Entry KEY_GENERIC_TYPE subLowest(); protected abstract Entry KEY_GENERIC_TYPE subHighest(); protected abstract Entry KEY_GENERIC_TYPE subCeiling(KEY_TYPE key); protected abstract Entry KEY_GENERIC_TYPE subHigher(KEY_TYPE key); protected abstract Entry KEY_GENERIC_TYPE subFloor(KEY_TYPE key); protected abstract Entry KEY_GENERIC_TYPE subLower(KEY_TYPE key); protected KEY_TYPE lowKeyOrNull(Entry KEY_GENERIC_TYPE entry) { return entry == null ? getDefaultMinValue() : entry.key; } protected KEY_TYPE highKeyOrNull(Entry KEY_GENERIC_TYPE entry) { return entry == null ? getDefaultMaxValue() : entry.key; } protected abstract Entry KEY_GENERIC_TYPE start(); protected abstract Entry KEY_GENERIC_TYPE next(Entry KEY_GENERIC_TYPE entry); final Entry KEY_GENERIC_TYPE absLowest() { Entry KEY_GENERIC_TYPE e = (fromStart ? set.first : (loInclusive ? set.findCeilingNode(lo) : set.findHigherNode(lo))); return (e == null || tooHigh(e.key)) ? null : e; } final Entry KEY_GENERIC_TYPE absHighest() { Entry KEY_GENERIC_TYPE e = (toEnd ? set.last : (hiInclusive ? set.findFloorNode(hi) : set.findLowerNode(hi))); return (e == null || tooLow(e.key)) ? null : e; } final Entry KEY_GENERIC_TYPE absCeiling(KEY_TYPE key) { if (tooLow(key)) return absLowest(); Entry KEY_GENERIC_TYPE e = set.findCeilingNode(key); return (e == null || tooHigh(e.key)) ? null : e; } final Entry KEY_GENERIC_TYPE absHigher(KEY_TYPE key) { if (tooLow(key)) return absLowest(); Entry KEY_GENERIC_TYPE e = set.findHigherNode(key); return (e == null || tooHigh(e.key)) ? null : e; } final Entry KEY_GENERIC_TYPE absFloor(KEY_TYPE key) { if (tooHigh(key)) return absHighest(); Entry KEY_GENERIC_TYPE e = set.findFloorNode(key); return (e == null || tooLow(e.key)) ? null : e; } final Entry KEY_GENERIC_TYPE absLower(KEY_TYPE key) { if (tooHigh(key)) return absHighest(); Entry KEY_GENERIC_TYPE e = set.findLowerNode(key); return (e == null || tooLow(e.key)) ? null : e; } final Entry KEY_GENERIC_TYPE absHighFence() { return (toEnd ? null : (hiInclusive ? set.findHigherNode(hi) : set.findCeilingNode(hi))); } final Entry KEY_GENERIC_TYPE absLowFence() { return (fromStart ? null : (loInclusive ? set.findLowerNode(lo) : set.findFloorNode(lo))); } @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 boolean isEmpty() { if(fromStart && toEnd) return set.isEmpty(); Entry KEY_GENERIC_TYPE n = absLowest(); return n == null || tooHigh(n.key); } @Override public int size() { if(fromStart && toEnd) return set.size(); int i = 0; for(ITERATOR KEY_GENERIC_TYPE iter = iterator();iter.hasNext();iter.NEXT(),i++); return i; } @Override public KEY_TYPE lower(KEY_TYPE e) { return lowKeyOrNull(subLower(e)); } @Override public KEY_TYPE floor(KEY_TYPE e) { return lowKeyOrNull(subFloor(e)); } @Override public KEY_TYPE ceiling(KEY_TYPE e) { return highKeyOrNull(subCeiling(e)); } @Override public KEY_TYPE higher(KEY_TYPE e) { return highKeyOrNull(subHigher(e)); } #if !TYPE_OBJECT @Override @Deprecated public CLASS_TYPE lower(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE entry = subLower(e); return entry == null ? null : KEY_TO_OBJ(entry.key); } @Override @Deprecated public CLASS_TYPE floor(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE entry = subFloor(e); return entry == null ? null : KEY_TO_OBJ(entry.key); } @Override @Deprecated public CLASS_TYPE ceiling(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE entry = subCeiling(e); return entry == null ? null : KEY_TO_OBJ(entry.key); } @Override @Deprecated public CLASS_TYPE higher(CLASS_TYPE e) { Entry KEY_GENERIC_TYPE entry = subHigher(e); return entry == null ? null : KEY_TO_OBJ(entry.key); } #endif @Override public KEY_TYPE POLL_FIRST_KEY() { Entry KEY_GENERIC_TYPE entry = subLowest(); if(entry != null) { KEY_TYPE result = entry.key; set.removeNode(entry); return result; } return getDefaultMinValue(); } @Override public KEY_TYPE POLL_LAST_KEY() { Entry KEY_GENERIC_TYPE entry = subHighest(); if(entry != null) { KEY_TYPE result = entry.key; set.removeNode(entry); return result; } return getDefaultMaxValue(); } @Override public KEY_TYPE FIRST_KEY() { Entry KEY_GENERIC_TYPE entry = subLowest(); if(entry == null) throw new NoSuchElementException(); return entry.key; } @Override public KEY_TYPE LAST_KEY() { Entry KEY_GENERIC_TYPE entry = subHighest(); if(entry == null) throw new NoSuchElementException(); return entry.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 SubSet KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); } @Override public void forEach(CONSUMER KEY_SUPER_GENERIC_TYPE action) { Objects.requireNonNull(action); for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { action.accept(entry.key); } } @Override public void forEach(E input, BI_FROM_OBJECT_CONSUMER KSK_GENERIC_TYPE action) { Objects.requireNonNull(action); for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) action.accept(input, entry.key); } @Override public boolean matchesAny(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { 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 = start();entry != null && inRange(entry.key);entry = next(entry)) { 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 = start();entry != null && inRange(entry.key);entry = next(entry)) { if(!filter.TEST_VALUE(entry.key)) return false; } return true; } #if !TYPE_OBJECT @Override public KEY_TYPE reduce(KEY_TYPE identity, UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { Objects.requireNonNull(operator); KEY_TYPE state = identity; for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { state = operator.APPLY_VALUE(state, entry.key); } return state; } #else @Override public KEY_SPECIAL_TYPE reduce(KEY_SPECIAL_TYPE identity, BiFunction operator) { Objects.requireNonNull(operator); KEY_SPECIAL_TYPE state = identity; for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { state = operator.APPLY_VALUE(state, entry.key); } return state; } #endif @Override public KEY_TYPE reduce(UNARY_OPERATOR KEY_KEY_GENERIC_TYPE operator) { Objects.requireNonNull(operator); KEY_TYPE state = EMPTY_VALUE; boolean empty = true; for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { if(empty) { empty = false; state = entry.key; continue; } state = operator.APPLY_VALUE(state, entry.key); } return state; } @Override public KEY_TYPE findFirst(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { if(filter.TEST_VALUE(entry.key)) return entry.key; } return EMPTY_VALUE; } @Override public int count(PREDICATE KEY_GENERIC_TYPE filter) { Objects.requireNonNull(filter); int result = 0; for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { if(filter.TEST_VALUE(entry.key)) result++; } return result; } class AscendingSubSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE { Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE next; boolean forwards = false; boolean unboundForwardFence; boolean unboundBackwardFence; KEY_TYPE forwardFence; KEY_TYPE backwardFence; public AscendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence) { next = 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; } @Override public boolean hasNext() { return next != null && (unboundForwardFence || next.key != forwardFence); } @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.next(); forwards = true; return result; } @Override public boolean hasPrevious() { return next != null && (unboundBackwardFence || next.key != backwardFence); } @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.previous(); forwards = false; return result; } @Override public void remove() { if(lastReturned == null) throw new IllegalStateException(); if(forwards && lastReturned.needsSuccessor()) next = lastReturned; set.removeNode(lastReturned); lastReturned = null; } } class DescendingSubSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE { Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE next; boolean forwards = false; boolean unboundForwardFence; boolean unboundBackwardFence; KEY_TYPE forwardFence; KEY_TYPE backwardFence; public DescendingSubSetIterator(Entry KEY_GENERIC_TYPE first, Entry KEY_GENERIC_TYPE forwardFence, Entry KEY_GENERIC_TYPE backwardFence) { next = 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; } @Override public boolean hasNext() { return next != null && (unboundForwardFence || next.key != forwardFence); } @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.previous(); forwards = false; return result; } @Override public boolean hasPrevious() { return next != null && (unboundBackwardFence || next.key != backwardFence); } @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.next(); forwards = true; return result; } @Override public void remove() { if(lastReturned == null) throw new IllegalStateException(); if(forwards && lastReturned.needsSuccessor()) next = lastReturned; set.removeNode(lastReturned); lastReturned = null; } } } class AscendingSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE { Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE next; boolean forwards = false; public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) { next = first; } @Override public boolean hasNext() { return next != null; } @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.next(); forwards = true; return result; } @Override public boolean hasPrevious() { return next != null; } @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.previous(); forwards = false; return result; } @Override public void remove() { if(lastReturned == null) throw new IllegalStateException(); if(forwards && lastReturned.needsSuccessor()) next = lastReturned; removeNode(lastReturned); lastReturned = null; } } class DescendingSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE { Entry KEY_GENERIC_TYPE lastReturned; Entry KEY_GENERIC_TYPE next; boolean forwards = false; public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) { next = first; } @Override public boolean hasNext() { return next != null; } @Override public KEY_TYPE NEXT() { if(!hasNext()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.previous(); forwards = false; return result; } @Override public boolean hasPrevious() { return next != null; } @Override public KEY_TYPE PREVIOUS() { if(!hasPrevious()) throw new NoSuchElementException(); lastReturned = next; KEY_TYPE result = next.key; next = next.next(); forwards = true; return result; } @Override public void remove() { if(lastReturned == null) throw new IllegalStateException(); if(forwards && lastReturned.needsSuccessor()) next = lastReturned; removeNode(lastReturned); lastReturned = null; } } private static final class Entry KEY_GENERIC_TYPE { 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; } Entry KEY_GENERIC_TYPE copy() { Entry KEY_GENERIC_TYPE entry = new EntryBRACES(key, null); entry.state = state; if(left != null) { Entry KEY_GENERIC_TYPE newLeft = left.copy(); entry.left = newLeft; newLeft.parent = entry; } if(right != null) { Entry KEY_GENERIC_TYPE newRight = right.copy(); entry.right = newRight; newRight.parent = entry; } return entry; } int getHeight() { return state; } void updateHeight() { state = (1 + Math.max(left == null ? -1 : left.getHeight(), right == null ? -1 : right.getHeight())); } int getBalance() { return (left == null ? -1 : left.getHeight()) - (right == null ? -1 : right.getHeight()); } 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; } } }