diff --git a/Changelog.md b/Changelog.md index 818499a..daf56fc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ ### Version 0.8.0 - Added: getFirst/getLast/removeFirst/removeLast to Lists +- Added: Dedicated implementations for toArray into TreeSets ### Version 0.8.0 - Added: ISizeProvider interface (Optimization Helper) diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template index b876f61..b33d309 100644 --- a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template +++ b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template @@ -382,13 +382,17 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends MapFastUtil, - * 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; - } - -#if TYPE_OBJECT - @Override - public KEY_TYPE addOrGet(KEY_TYPE o) { - validate(o); - if(tree == null) { - tree = first = last = new EntryBRACES(o, null); - size++; - return o; - } - int compare = 0; - Entry KEY_GENERIC_TYPE parent = tree; - while(true) { - if((compare = compare(o, parent.key)) == 0) return parent.key; - 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 o; - } - -#endif - @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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { - Objects.requireNonNull(action); - int index = 0; - for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { - action.accept(index++, 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(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(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(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(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(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; } - - @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, 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 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 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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { - Objects.requireNonNull(action); - int index = 0; - for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { - action.accept(index++, 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(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(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(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(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(entry.key)) result++; - } - return result; - } - - class AscendingSubSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE - { - Entry KEY_GENERIC_TYPE lastReturned; - Entry KEY_GENERIC_TYPE next; - Entry KEY_GENERIC_TYPE previous; - 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; - previous = first == null ? null : first.previous(); - 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; - previous = next; - KEY_TYPE result = next.key; - next = next.next(); - forwards = true; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null && (unboundBackwardFence || previous.key != backwardFence); - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.previous(); - forwards = false; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(previous == lastReturned) previous = previous.previous(); - if(next == lastReturned) next = next.next(); - 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; - Entry KEY_GENERIC_TYPE previous; - 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; - previous = first == null ? null : first.next(); - 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; - previous = next; - KEY_TYPE result = next.key; - next = next.previous(); - forwards = false; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null && (unboundBackwardFence || previous.key != backwardFence); - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.next(); - forwards = true; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(previous == lastReturned) previous = previous.next(); - if(next == lastReturned) next = next.previous(); - 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; - Entry KEY_GENERIC_TYPE previous; - boolean forwards = false; - - public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) - { - next = first; - previous = first == null ? null : first.previous(); - } - - @Override - public boolean hasNext() { - return next != null; - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - lastReturned = next; - previous = next; - KEY_TYPE result = next.key; - next = next.next(); - forwards = true; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null; - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.previous(); - forwards = false; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(lastReturned == previous) previous = previous.previous(); - if(lastReturned == next) next = next.next(); - 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; - Entry KEY_GENERIC_TYPE previous; - boolean forwards = false; - - public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) - { - next = first; - previous = first == null ? null : first.next(); - } - - @Override - public boolean hasNext() { - return next != null; - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - lastReturned = next; - previous = next; - KEY_TYPE result = next.key; - next = next.previous(); - forwards = false; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null; - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.next(); - forwards = true; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(lastReturned == previous) previous = previous.next(); - if(lastReturned == next) next = next.previous(); - 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; - } - } -} +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; +#if JDK_FUNCTION +import java.util.function.PREDICATE; +#endif + +import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +import speiger.src.collections.PACKAGE.functions.CONSUMER; +#endif +import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER; +import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; +#if !JDK_FUNCTION +import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#endif +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.PACKAGE.collections.COLLECTION; +import speiger.src.collections.PACKAGE.collections.ITERATOR; +import speiger.src.collections.objects.utils.ObjectArrays; +#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; + } + +#if TYPE_OBJECT + @Override + public KEY_TYPE addOrGet(KEY_TYPE o) { + validate(o); + if(tree == null) { + tree = first = last = new EntryBRACES(o, null); + size++; + return o; + } + int compare = 0; + Entry KEY_GENERIC_TYPE parent = tree; + while(true) { + if((compare = compare(o, parent.key)) == 0) return parent.key; + 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 o; + } + +#endif + @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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { + Objects.requireNonNull(action); + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + action.accept(index++, 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(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(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(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(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(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; + } + +#if !TYPE_OBJECT + @Override + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { + if(a == null || a.length < size()) a = new KEY_TYPE[size()]; + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + a[index++] = entry.key; + } + if (a.length > size) a[size] = EMPTY_KEY_VALUE; + return a; + } + +#endif + @Override + @Deprecated + public Object[] toArray() { + if(isEmpty()) return ObjectArrays.EMPTY_ARRAY; + Object[] obj = new Object[size()]; + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + obj[index++] = KEY_TO_OBJ(entry.key); + } + return obj; + } + + @Override + @Primitive + public E[] toArray(E[] a) { + if(a == null) a = (E[])new Object[size()]; + else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size()); + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + a[index++] = (E)KEY_TO_OBJ(entry.key); + } + if (a.length > size) a[size] = null; + return a; + } + + 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; } + + @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, 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 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 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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { + Objects.requireNonNull(action); + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + action.accept(index++, 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(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(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(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(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(entry.key)) result++; + } + return result; + } + + class AscendingSubSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE + { + Entry KEY_GENERIC_TYPE lastReturned; + Entry KEY_GENERIC_TYPE next; + Entry KEY_GENERIC_TYPE previous; + 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; + previous = first == null ? null : first.previous(); + 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; + previous = next; + KEY_TYPE result = next.key; + next = next.next(); + forwards = true; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null && (unboundBackwardFence || previous.key != backwardFence); + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.previous(); + forwards = false; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(previous == lastReturned) previous = previous.previous(); + if(next == lastReturned) next = next.next(); + 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; + Entry KEY_GENERIC_TYPE previous; + 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; + previous = first == null ? null : first.next(); + 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; + previous = next; + KEY_TYPE result = next.key; + next = next.previous(); + forwards = false; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null && (unboundBackwardFence || previous.key != backwardFence); + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.next(); + forwards = true; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(previous == lastReturned) previous = previous.next(); + if(next == lastReturned) next = next.previous(); + 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; + Entry KEY_GENERIC_TYPE previous; + boolean forwards = false; + + public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) + { + next = first; + previous = first == null ? null : first.previous(); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + lastReturned = next; + previous = next; + KEY_TYPE result = next.key; + next = next.next(); + forwards = true; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null; + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.previous(); + forwards = false; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(lastReturned == previous) previous = previous.previous(); + if(lastReturned == next) next = next.next(); + 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; + Entry KEY_GENERIC_TYPE previous; + boolean forwards = false; + + public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) + { + next = first; + previous = first == null ? null : first.next(); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + lastReturned = next; + previous = next; + KEY_TYPE result = next.key; + next = next.previous(); + forwards = false; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null; + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.next(); + forwards = true; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(lastReturned == previous) previous = previous.next(); + if(lastReturned == next) next = next.previous(); + 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; + } + } +} diff --git a/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template b/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template index c7d5a83..987eefa 100644 --- a/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template +++ b/src/builder/resources/speiger/assets/collections/templates/sets/RBTreeSet.template @@ -1,1694 +1,1733 @@ -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; -#if JDK_FUNCTION -import java.util.function.PREDICATE; -#endif - -import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; -#if !TYPE_OBJECT -import speiger.src.collections.PACKAGE.functions.COMPARATOR; -import speiger.src.collections.PACKAGE.functions.CONSUMER; -#endif -import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER; -import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; -#if !JDK_FUNCTION -import speiger.src.collections.PACKAGE.functions.function.PREDICATE; -#endif -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 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; } - -#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; - } - -#if TYPE_OBJECT - @Override - public KEY_TYPE addOrGet(KEY_TYPE o) { - validate(o); - if(tree == null) { - tree = first = last = new EntryBRACES(o, null); - size++; - return o; - } - int compare = 0; - Entry KEY_GENERIC_TYPE parent = tree; - while(true) { - if((compare = compare(o, parent.key)) == 0) return parent.key; - 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 o; - } - -#endif - @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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { - Objects.requireNonNull(action); - int index = 0; - for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) - action.accept(index++, 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(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(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(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 = 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 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(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 = first;entry != null;entry = entry.next()) { - if(filter.test(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 RB_TREE_SET KEY_GENERIC_TYPE copy() { - RB_TREE_SET KEY_GENERIC_TYPE set = new RB_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; - } - 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 void validate(KEY_TYPE k) { compare(k, k); } - protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);} - protected static GENERIC_KEY_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); - } - - static class AscendingSubSet KEY_GENERIC_TYPE extends SubSet KEY_GENERIC_TYPE - { - public AscendingSubSet(RB_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(RB_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; } - - @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, 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 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 RB_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(RB_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 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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { - Objects.requireNonNull(action); - int index = 0; - for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { - action.accept(index++, 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(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(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(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(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(entry.key)) result++; - } - return result; - } - - class AscendingSubSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE - { - Entry KEY_GENERIC_TYPE lastReturned; - Entry KEY_GENERIC_TYPE next; - Entry KEY_GENERIC_TYPE previous; - 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; - previous = first == null ? null : first.previous(); - 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; - previous = next; - KEY_TYPE result = next.key; - next = next.next(); - forwards = true; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null && (unboundBackwardFence || previous.key != backwardFence); - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.previous(); - forwards = false; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(previous == lastReturned) previous = previous.previous(); - if(next == lastReturned) next = next.next(); - 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; - Entry KEY_GENERIC_TYPE previous; - 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; - previous = first == null ? null : first.next(); - 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; - previous = next; - KEY_TYPE result = next.key; - next = next.previous(); - forwards = false; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null && (unboundBackwardFence || previous.key != backwardFence); - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.next(); - forwards = true; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(previous == lastReturned) previous = previous.next(); - if(next == lastReturned) next = next.previous(); - 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; - Entry KEY_GENERIC_TYPE previous; - boolean forwards = false; - - public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) - { - next = first; - previous = first == null ? null : first.previous(); - } - - @Override - public boolean hasNext() { - return next != null; - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - lastReturned = next; - previous = next; - KEY_TYPE result = next.key; - next = next.next(); - forwards = true; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null; - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.previous(); - forwards = false; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(lastReturned == previous) previous = previous.previous(); - if(lastReturned == next) next = next.next(); - 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; - Entry KEY_GENERIC_TYPE previous; - boolean forwards = false; - - public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) - { - next = first; - previous = first == null ? null : first.next(); - } - - @Override - public boolean hasNext() { - return next != null; - } - - @Override - public KEY_TYPE NEXT() { - if(!hasNext()) throw new NoSuchElementException(); - lastReturned = next; - previous = next; - KEY_TYPE result = next.key; - next = next.previous(); - forwards = false; - return result; - } - - @Override - public boolean hasPrevious() { - return previous != null; - } - - @Override - public KEY_TYPE PREVIOUS() { - if(!hasPrevious()) throw new NoSuchElementException(); - lastReturned = previous; - next = previous; - KEY_TYPE result = previous.key; - previous = previous.next(); - forwards = true; - return result; - } - - @Override - public void remove() { - if(lastReturned == null) throw new IllegalStateException(); - if(lastReturned == previous) previous = previous.next(); - if(lastReturned == next) next = next.previous(); - if(forwards && lastReturned.needsSuccessor()) next = lastReturned; - removeNode(lastReturned); - lastReturned = null; - } - } - - 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; - } - - 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; - } - - 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; - } - } -} +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; +#if JDK_FUNCTION +import java.util.function.PREDICATE; +#endif + +import speiger.src.collections.PACKAGE.collections.BI_ITERATOR; +#if !TYPE_OBJECT +import speiger.src.collections.PACKAGE.functions.COMPARATOR; +import speiger.src.collections.PACKAGE.functions.CONSUMER; +#endif +import speiger.src.collections.ints.functions.consumer.BI_FROM_INT_CONSUMER; +import speiger.src.collections.objects.functions.consumer.BI_FROM_OBJECT_CONSUMER; +#if !JDK_FUNCTION +import speiger.src.collections.PACKAGE.functions.function.PREDICATE; +#endif +import speiger.src.collections.PACKAGE.functions.function.UNARY_OPERATOR; +import speiger.src.collections.PACKAGE.collections.COLLECTION; +import speiger.src.collections.PACKAGE.collections.ITERATOR; +import speiger.src.collections.objects.utils.ObjectArrays; +#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; } + +#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; + } + +#if TYPE_OBJECT + @Override + public KEY_TYPE addOrGet(KEY_TYPE o) { + validate(o); + if(tree == null) { + tree = first = last = new EntryBRACES(o, null); + size++; + return o; + } + int compare = 0; + Entry KEY_GENERIC_TYPE parent = tree; + while(true) { + if((compare = compare(o, parent.key)) == 0) return parent.key; + 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 o; + } + +#endif + @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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { + Objects.requireNonNull(action); + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) + action.accept(index++, 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(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(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(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 = 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 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(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 = first;entry != null;entry = entry.next()) { + if(filter.test(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; + } + +#if !TYPE_OBJECT + @Override + public KEY_TYPE[] TO_ARRAY(KEY_TYPE[] a) { + if(a == null || a.length < size()) a = new KEY_TYPE[size()]; + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + a[index++] = entry.key; + } + if (a.length > size) a[size] = EMPTY_KEY_VALUE; + return a; + } + +#endif + @Override + @Deprecated + public Object[] toArray() { + if(isEmpty()) return ObjectArrays.EMPTY_ARRAY; + Object[] obj = new Object[size()]; + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + obj[index++] = KEY_TO_OBJ(entry.key); + } + return obj; + } + + @Override + @Primitive + public E[] toArray(E[] a) { + if(a == null) a = (E[])new Object[size()]; + else if(a.length < size()) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size()); + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = first;entry != null;entry = entry.next()) { + a[index++] = (E)KEY_TO_OBJ(entry.key); + } + if (a.length > size) a[size] = null; + return a; + } + + public RB_TREE_SET KEY_GENERIC_TYPE copy() { + RB_TREE_SET KEY_GENERIC_TYPE set = new RB_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; + } + 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 void validate(KEY_TYPE k) { compare(k, k); } + protected int compare(KEY_TYPE k, KEY_TYPE v) { return comparator != null ? comparator.compare(k, v) : COMPAREABLE_TO_KEY(k, v);} + protected static GENERIC_KEY_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); + } + + static class AscendingSubSet KEY_GENERIC_TYPE extends SubSet KEY_GENERIC_TYPE + { + public AscendingSubSet(RB_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(RB_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; } + + @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, 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 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 RB_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(RB_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 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 forEachIndexed(BI_FROM_INT_CONSUMER KEY_GENERIC_TYPE action) { + Objects.requireNonNull(action); + int index = 0; + for(Entry KEY_GENERIC_TYPE entry = start();entry != null && inRange(entry.key);entry = next(entry)) { + action.accept(index++, 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(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(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(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(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(entry.key)) result++; + } + return result; + } + + class AscendingSubSetIterator implements BI_ITERATOR KEY_GENERIC_TYPE + { + Entry KEY_GENERIC_TYPE lastReturned; + Entry KEY_GENERIC_TYPE next; + Entry KEY_GENERIC_TYPE previous; + 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; + previous = first == null ? null : first.previous(); + 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; + previous = next; + KEY_TYPE result = next.key; + next = next.next(); + forwards = true; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null && (unboundBackwardFence || previous.key != backwardFence); + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.previous(); + forwards = false; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(previous == lastReturned) previous = previous.previous(); + if(next == lastReturned) next = next.next(); + 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; + Entry KEY_GENERIC_TYPE previous; + 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; + previous = first == null ? null : first.next(); + 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; + previous = next; + KEY_TYPE result = next.key; + next = next.previous(); + forwards = false; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null && (unboundBackwardFence || previous.key != backwardFence); + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.next(); + forwards = true; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(previous == lastReturned) previous = previous.next(); + if(next == lastReturned) next = next.previous(); + 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; + Entry KEY_GENERIC_TYPE previous; + boolean forwards = false; + + public AscendingSetIterator(Entry KEY_GENERIC_TYPE first) + { + next = first; + previous = first == null ? null : first.previous(); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + lastReturned = next; + previous = next; + KEY_TYPE result = next.key; + next = next.next(); + forwards = true; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null; + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.previous(); + forwards = false; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(lastReturned == previous) previous = previous.previous(); + if(lastReturned == next) next = next.next(); + 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; + Entry KEY_GENERIC_TYPE previous; + boolean forwards = false; + + public DescendingSetIterator(Entry KEY_GENERIC_TYPE first) + { + next = first; + previous = first == null ? null : first.next(); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public KEY_TYPE NEXT() { + if(!hasNext()) throw new NoSuchElementException(); + lastReturned = next; + previous = next; + KEY_TYPE result = next.key; + next = next.previous(); + forwards = false; + return result; + } + + @Override + public boolean hasPrevious() { + return previous != null; + } + + @Override + public KEY_TYPE PREVIOUS() { + if(!hasPrevious()) throw new NoSuchElementException(); + lastReturned = previous; + next = previous; + KEY_TYPE result = previous.key; + previous = previous.next(); + forwards = true; + return result; + } + + @Override + public void remove() { + if(lastReturned == null) throw new IllegalStateException(); + if(lastReturned == previous) previous = previous.next(); + if(lastReturned == next) next = next.previous(); + if(forwards && lastReturned.needsSuccessor()) next = lastReturned; + removeNode(lastReturned); + lastReturned = null; + } + } + + 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; + } + + 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; + } + + 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; + } + } +}