diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java index 491cd8aa0..acf784d67 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeMap.java @@ -33,47 +33,18 @@ package org.teavm.classlib.java.util; import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.lang.*; -import org.teavm.javascript.ni.Rename; -public class TTreeMap extends TAbstractMap implements TSortedMap, TCloneable, TSerializable { - transient int size; - private TComparator comparator; - transient int modCount; - transient TSet> entrySet; - transient Node root; +public class TTreeMap extends TAbstractMap implements TCloneable, TSerializable, TSortedMap { + class TreeNode implements Entry { + K key; + V value; + TreeNode left; + TreeNode right; + int height = 1; + int size = 1; - class MapEntry extends TObject implements Entry, TCloneable { - final int offset; - final Node node; - final K key; - - MapEntry(Node node, int offset) { - this.node = node; - this.offset = offset; - key = node.keys[offset]; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (TCloneNotSupportedException e) { - return null; - } - } - - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object instanceof Entry) { - Entry entry = (Entry) object; - V value = getValue(); - return (key == null ? entry.getKey() == null : key.equals(entry.getKey())) - && (value == null ? entry.getValue() == null : value.equals(entry.getValue())); - } - return false; + public TreeNode(K key) { + this.key = key; } @Override @@ -83,2067 +54,331 @@ public class TTreeMap extends TAbstractMap implements TSortedMap 0) { + left = left.rotateLeft(); + } + return rotateRight(); + } else { + return this; } - if (containsKey(key)) { - return put(key, object); - } - throw new TIllegalStateException(); } - @Override - public String toString() { - return key + "=" + getValue(); - } - } - - static class Node extends TObject implements TCloneable { - static final int NODE_SIZE = 64; - Node prev, next; - Node parent, left, right; - V[] values; - K[] keys; - int left_idx = 0; - int right_idx = -1; - int size = 0; - boolean color; - - @SuppressWarnings("unchecked") - public Node() { - keys = (K[]) new Object[NODE_SIZE]; - values = (V[]) new Object[NODE_SIZE]; + public int factor() { + return (right != null ? right.height : 0) - (left != null ? left.height : 0); } - @SuppressWarnings("unchecked") - Node clone(Node parent) throws TCloneNotSupportedException { - Node clone = (Node) super.clone(); - clone.keys = TArrays.copyOf(keys, keys.length); - clone.values = TArrays.copyOf(values, values.length); - clone.left_idx = left_idx; - clone.right_idx = right_idx; - clone.parent = parent; + public TreeNode rotateRight() { + TreeNode left = this.left; + this.left = left.right; + left.right = this; + fix(); + left.fix(); + return left; + } + + public TreeNode rotateLeft() { + TreeNode right = this.right; + this.right = right.left; + right.left = this; + fix(); + right.fix(); + return right; + } + + public void fix() { + height = Math.max(right != null ? right.height : 0, left != null ? left.height : 0) + 1; + size = 1; if (left != null) { - clone.left = left.clone(clone); + size += left.size; } if (right != null) { - clone.right = right.clone(clone); - } - clone.prev = null; - clone.next = null; - return clone; - } - } - - @SuppressWarnings("unchecked") - private static TComparable toComparable(T obj) { - if (obj == null) { - throw new TNullPointerException(); - } - return (TComparable) obj; - } - - static class AbstractMapIterator { - TTreeMap backingMap; - int expectedModCount; - Node node; - Node lastNode; - int offset; - int lastOffset; - - AbstractMapIterator(TTreeMap map, Node startNode, int startOffset) { - backingMap = map; - expectedModCount = map.modCount; - node = startNode; - offset = startOffset; - } - - AbstractMapIterator(TTreeMap map, Node startNode) { - this(map, startNode, startNode != null ? startNode.right_idx - startNode.left_idx : 0); - } - - AbstractMapIterator(TTreeMap map) { - this(map, minimum(map.root)); - } - - public boolean hasNext() { - return node != null; - } - - final void makeNext() { - if (expectedModCount != backingMap.modCount) { - throw new TConcurrentModificationException(); - } else if (node == null) { - throw new TNoSuchElementException(); - } - lastNode = node; - lastOffset = offset; - if (offset != 0) { - offset--; - } else { - node = node.next; - if (node != null) { - offset = node.right_idx - node.left_idx; - } - } - } - - final public void remove() { - if (expectedModCount == backingMap.modCount) { - if (lastNode != null) { - int idx = lastNode.right_idx - lastOffset; - backingMap.removeFromIterator(lastNode, idx); - lastNode = null; - expectedModCount++; - } else { - throw new TIllegalStateException(); - } - } else { - throw new TConcurrentModificationException(); + size += right.size; } } } - static class UnboundedEntryIterator extends AbstractMapIterator - implements TIterator> { - - UnboundedEntryIterator(TTreeMap map, Node startNode, int startOffset) { - super(map, startNode, startOffset); - } - - UnboundedEntryIterator(TTreeMap map) { - super(map); - } - - @Override - public Entry next() { - makeNext(); - int idx = lastNode.right_idx - lastOffset; - return backingMap.new MapEntry(lastNode, idx); - } - } - - static class UnboundedKeyIterator extends AbstractMapIterator - implements TIterator { - - UnboundedKeyIterator(TTreeMap map, Node startNode, int startOffset) { - super(map, startNode, startOffset); - } - - UnboundedKeyIterator(TTreeMap map) { - super(map); - } - - @Override - public K next() { - makeNext(); - return lastNode.keys[lastNode.right_idx - lastOffset]; - } - } - - static class UnboundedValueIterator extends AbstractMapIterator - implements TIterator { - - UnboundedValueIterator(TTreeMap map, Node startNode, int startOffset) { - super(map, startNode, startOffset); - } - - UnboundedValueIterator(TTreeMap map) { - super(map); - } - - @Override - public V next() { - makeNext(); - return lastNode.values[lastNode.right_idx - lastOffset]; - } - } - - static class BoundedMapIterator extends AbstractMapIterator { - - Node finalNode; - int finalOffset; - - BoundedMapIterator(Node startNode, int startOffset, TTreeMap map, - Node finalNode, int finalOffset) { - super(map, finalNode == null ? null : startNode, startOffset); - this.finalNode = finalNode; - this.finalOffset = finalOffset; - } - - BoundedMapIterator(Node startNode, TTreeMap map, - Node finalNode, int finalOffset) { - this(startNode, startNode != null ? - startNode.right_idx - startNode.left_idx : 0, - map, finalNode, finalOffset); - } - - BoundedMapIterator(Node startNode, int startOffset, - TTreeMap map, Node finalNode) { - this(startNode, startOffset, map, finalNode, - finalNode.right_idx - finalNode.left_idx); - } - - void makeBoundedNext() { - makeNext(); - if (lastNode == finalNode && lastOffset == finalOffset) { - node = null; - } - } - } - - static class BoundedEntryIterator extends BoundedMapIterator - implements TIterator> { - - public BoundedEntryIterator(Node startNode, int startOffset, TTreeMap map, - Node finalNode, int finalOffset) { - super(startNode, startOffset, map, finalNode, finalOffset); - } - - @Override - public Entry next() { - makeBoundedNext(); - int idx = lastNode.right_idx - lastOffset; - return backingMap.new MapEntry(lastNode, idx); - } - } - - static class BoundedKeyIterator extends BoundedMapIterator - implements TIterator { - - public BoundedKeyIterator(Node startNode, int startOffset, TTreeMap map, - Node finalNode, int finalOffset) { - super(startNode, startOffset, map, finalNode, finalOffset); - } - - @Override - public K next() { - makeBoundedNext(); - return lastNode.keys[lastNode.right_idx - lastOffset]; - } - } - - static class BoundedValueIterator extends BoundedMapIterator - implements TIterator { - - public BoundedValueIterator(Node startNode, int startOffset, TTreeMap map, - Node finalNode, int finalOffset) { - super(startNode, startOffset, map, finalNode, finalOffset); - } - - @Override - public V next() { - makeBoundedNext(); - return lastNode.values[lastNode.right_idx - lastOffset]; - } - } - - static final class SubMap extends TAbstractMap - implements TSortedMap, TSerializable { - private TTreeMap backingMap; - boolean hasStart, hasEnd; - K startKey, endKey; - transient TSet> entrySet = null; - transient int firstKeyModCount = -1; - transient int lastKeyModCount = -1; - transient Node firstKeyNode; - transient int firstKeyIndex; - transient Node lastKeyNode; - transient int lastKeyIndex; - - SubMap(K start, TTreeMap map) { - backingMap = map; - hasStart = true; - startKey = start; - } - - SubMap(K start, TTreeMap map, K end) { - backingMap = map; - hasStart = hasEnd = true; - startKey = start; - endKey = end; - } - - SubMap(TTreeMap map, K end) { - backingMap = map; - hasEnd = true; - endKey = end; - } - - private void checkRange(K key) { - TComparator cmp = backingMap.comparator; - if (cmp == null) { - TComparable object = toComparable(key); - if (hasStart && object.compareTo(startKey) < 0) { - throw new TIllegalArgumentException(); - } - if (hasEnd && object.compareTo(endKey) > 0) { - throw new TIllegalArgumentException(); - } - } else { - if (hasStart - && backingMap.comparator().compare(key, startKey) < 0) { - throw new TIllegalArgumentException(); - } - if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) { - throw new TIllegalArgumentException(); - } - } - } - - private boolean isInRange(K key) { - TComparator cmp = backingMap.comparator; - if (cmp == null) { - TComparable object = toComparable(key); - if (hasStart && object.compareTo(startKey) < 0) { - return false; - } - if (hasEnd && object.compareTo(endKey) >= 0) { - return false; - } - } else { - if (hasStart && cmp.compare(key, startKey) < 0) { - return false; - } - if (hasEnd && cmp.compare(key, endKey) >= 0) { - return false; - } - } - return true; - } - - private boolean checkUpperBound(K key) { - if (hasEnd) { - TComparator cmp = backingMap.comparator; - if (cmp == null) { - return (toComparable(key).compareTo(endKey) < 0); - } - return (cmp.compare(key, endKey) < 0); - } - return true; - } - - private boolean checkLowerBound(K key) { - if (hasStart) { - TComparator cmp = backingMap.comparator; - if (cmp == null) { - return (toComparable(key).compareTo(startKey) >= 0); - } - return (cmp.compare(key, startKey) >= 0); - } - return true; - } - - @Override - public TComparator comparator() { - return backingMap.comparator(); - } - - @SuppressWarnings("unchecked") - @Override - public boolean containsKey(Object key) { - if (isInRange((K) key)) { - return backingMap.containsKey(key); - } - return false; - } - - @Override - public void clear() { - keySet().clear(); - } - - @Override - public boolean containsValue(Object value) { - TIterator it = values().iterator(); - if (value != null) { - while (it.hasNext()) { - if (value.equals(it.next())) { - return true; - } - } - } else { - while (it.hasNext()) { - if (it.next() == null) { - return true; - } - } - } - return false; - } - - @Override - public TSet> entrySet() { - if (entrySet == null) { - entrySet = new SubMapEntrySet<>(this); - } - return entrySet; - } - - private void setFirstKey() { - if (firstKeyModCount == backingMap.modCount) { - return; - } - TComparable object = backingMap.comparator == null ? toComparable(startKey) : null; - K key = startKey; - Node node = backingMap.root; - Node foundNode = null; - int foundIndex = -1; - TOP_LOOP: - while (node != null) { - K[] keys = node.keys; - int left_idx = node.left_idx; - int result = backingMap.cmp(object, key, keys[left_idx]); - if (result < 0) { - foundNode = node; - foundIndex = left_idx; - node = node.left; - } else if (result == 0) { - foundNode = node; - foundIndex = left_idx; - break; - } else { - int right_idx = node.right_idx; - if (left_idx != right_idx) { - result = backingMap.cmp(object, key, keys[right_idx]); - } - if (result > 0) { - node = node.right; - } else if (result == 0) { - foundNode = node; - foundIndex = right_idx; - break; - } else { /*search in node*/ - foundNode = node; - foundIndex = right_idx; - int low = left_idx + 1, mid = 0, high = right_idx - 1; - while (low <= high) { - mid = (low + high) >>> 1; - result = backingMap.cmp(object, key, keys[mid]); - if (result > 0) { - low = mid + 1; - } else if (result == 0) { - foundNode = node; - foundIndex = mid; - break TOP_LOOP; - } else { - foundNode = node; - foundIndex = mid; - high = mid - 1; - } - } - break TOP_LOOP; - } - } - } - if (foundNode != null && !checkUpperBound(foundNode.keys[foundIndex])) { - foundNode = null; - } - firstKeyNode = foundNode; - firstKeyIndex = foundIndex; - firstKeyModCount = backingMap.modCount; - } - - @Override - public K firstKey() { - if (backingMap.size > 0) { - if (!hasStart) { - Node node = minimum(backingMap.root); - if (node != null && checkUpperBound(node.keys[node.left_idx])) { - return node.keys[node.left_idx]; - } - } else { - setFirstKey(); - if (firstKeyNode != null) { - return firstKeyNode.keys[firstKeyIndex]; - } - } - } - throw new TNoSuchElementException(); - } - - - @SuppressWarnings("unchecked") - @Override - public V get(Object key) { - if (isInRange((K) key)) { - return backingMap.get(key); - } - return null; - } - - @Override - public TSortedMap headMap(K endKey) { - checkRange(endKey); - if (hasStart) { - return new SubMap<>(startKey, backingMap, endKey); - } - return new SubMap<>(backingMap, endKey); - } - - @Override - public boolean isEmpty() { - if (hasStart) { - setFirstKey(); - return firstKeyNode == null; - } else { - setLastKey(); - return lastKeyNode == null; - } - } - - @Override - public TSet keySet() { - if (cachedKeySet == null) { - cachedKeySet = new SubMapKeySet<>(this); - } - return cachedKeySet; - } - - private void setLastKey() { - if (lastKeyModCount == backingMap.modCount) { - return; - } - TComparable object = backingMap.comparator == null ? toComparable(endKey) : null; - K key = endKey; - Node node = backingMap.root; - Node foundNode = null; - int foundIndex = -1; - TOP_LOOP: - while (node != null) { - K[] keys = node.keys; - int left_idx = node.left_idx; - int result = backingMap.cmp(object, key, keys[left_idx]); - if (result <= 0) { - node = node.left; - } else { - int right_idx = node.right_idx; - if (left_idx != right_idx) { - result = backingMap.cmp(object, key, keys[right_idx]); - } - if (result > 0) { - foundNode = node; - foundIndex = right_idx; - node = node.right; - } else if (result == 0) { - if (node.left_idx == node.right_idx) { - foundNode = node.prev; - if (foundNode != null) { - foundIndex = foundNode.right_idx - 1; - } - } else { - foundNode = node; - foundIndex = right_idx - 1; - } - break; - } else { /*search in node*/ - foundNode = node; - foundIndex = left_idx; - int low = left_idx + 1, mid = 0, high = right_idx - 1; - while (low <= high) { - mid = (low + high) >>> 1; - result = backingMap.cmp(object, key, keys[mid]); - if (result > 0) { - foundNode = node; - foundIndex = mid; - low = mid + 1; - } else if (result == 0) { - foundNode = node; - foundIndex = mid - 1; - break TOP_LOOP; - } else { - high = mid - 1; - } - } - break TOP_LOOP; - } - } - } - if (foundNode != null && !checkLowerBound(foundNode.keys[foundIndex])) { - foundNode = null; - } - lastKeyNode = foundNode; - lastKeyIndex = foundIndex; - lastKeyModCount = backingMap.modCount; - } - - @Override - public K lastKey() { - if (backingMap.size > 0) { - if (!hasEnd) { - Node node = maximum(backingMap.root); - if (node != null && checkLowerBound(node.keys[node.right_idx])) { - return node.keys[node.right_idx]; - } - } else { - setLastKey(); - if (lastKeyNode != null) { - return lastKeyNode.keys[lastKeyIndex]; - } - } - } - throw new TNoSuchElementException(); - } - - - @Override - public V put(K key, V value) { - if (isInRange(key)) { - return backingMap.put(key, value); - } - throw new TIllegalArgumentException(); - } - - @SuppressWarnings("unchecked") - @Override - public V remove(Object key) { - if (isInRange((K) key)) { - return backingMap.remove(key); - } - return null; - } - - @Override - public TSortedMap subMap(K startKey, K endKey) { - checkRange(startKey); - checkRange(endKey); - TComparator c = backingMap.comparator(); - if (c == null) { - if (toComparable(startKey).compareTo(endKey) <= 0) { - return new SubMap<>(startKey, backingMap, endKey); - } - } else { - if (c.compare(startKey, endKey) <= 0) { - return new SubMap<>(startKey, backingMap, endKey); - } - } - throw new IllegalArgumentException(); - } - - @Override - public TSortedMap tailMap(K startKey) { - checkRange(startKey); - if (hasEnd) { - return new SubMap<>(startKey, backingMap, endKey); - } - return new SubMap<>(startKey, backingMap); - } - - @Override - public TCollection values() { - if (cachedValues == null) { - cachedValues = new SubMapValuesCollection<>(this); - } - return cachedValues; - } - - @Override - public int size() { - Node from, to; - int fromIndex, toIndex; - if (hasStart) { - setFirstKey(); - from = firstKeyNode; - fromIndex = firstKeyIndex; - } else { - from = minimum(backingMap.root); - fromIndex = from == null ? 0 : from.left_idx; - } - if (from == null) { - return 0; - } - if (hasEnd) { - setLastKey(); - to = lastKeyNode; - toIndex = lastKeyIndex; - } else { - to = maximum(backingMap.root); - toIndex = to == null ? 0 : to.right_idx; - } - if (to == null) { - return 0; - } - if (from == to) { - return toIndex - fromIndex + 1; - } - int sum = 0; - while (from != to) { - sum += (from.right_idx - fromIndex + 1); - from = from.next; - fromIndex = from.left_idx; - } - return sum + toIndex - fromIndex + 1; - } - - } - - static class SubMapEntrySet extends TAbstractSet> { - SubMap subMap; - - SubMapEntrySet(SubMap map) { - subMap = map; - } - - @Override - public boolean isEmpty() { - return subMap.isEmpty(); - } - - @Override - public TIterator> iterator() { - Node from; - int fromIndex; - if (subMap.hasStart) { - subMap.setFirstKey(); - from = subMap.firstKeyNode; - fromIndex = subMap.firstKeyIndex; - } else { - from = minimum(subMap.backingMap.root); - fromIndex = from != null ? from.left_idx : 0; - } - if (!subMap.hasEnd) { - return new UnboundedEntryIterator<>(subMap.backingMap, from, - from == null ? 0 : from.right_idx - fromIndex); - } - subMap.setLastKey(); - Node to = subMap.lastKeyNode; - int toIndex = subMap.lastKeyIndex; - return new BoundedEntryIterator<>(from, from == null ? 0 : from.right_idx - fromIndex, - subMap.backingMap, to, to == null ? 0 : to.right_idx - toIndex); - } - - @Override - public int size() { - return subMap.size(); - } - - @SuppressWarnings("unchecked") - @Override - public boolean contains(Object object) { - if (object instanceof Entry) { - Entry entry = (Entry) object; - K key = entry.getKey(); - if (subMap.isInRange(key)) { - V v1 = subMap.get(key), v2 = entry.getValue(); - return v1 == null ? ( v2 == null && subMap.containsKey(key) ) : v1.equals(v2); - } - } - return false; - } - - @Override - public boolean remove(Object object) { - if (contains(object)) { - @SuppressWarnings("unchecked") - Entry entry = (Entry) object; - K key = entry.getKey(); - subMap.remove(key); - return true; - } - return false; - } - } - - static class SubMapKeySet extends TAbstractSet { - SubMap subMap; - - SubMapKeySet(SubMap map) { - subMap = map; - } - - @Override - public boolean contains(Object object) { - return subMap.containsKey(object); - } - - @Override - public boolean isEmpty() { - return subMap.isEmpty(); - } - - @Override - public int size() { - return subMap.size(); - } - - @Override - public boolean remove(Object object) { - if (subMap.containsKey(object)) { - subMap.remove(object); - return true; - } - return false; - } - - @Override - public TIterator iterator() { - Node from; - int fromIndex; - if (subMap.hasStart) { - subMap.setFirstKey(); - from = subMap.firstKeyNode; - fromIndex = subMap.firstKeyIndex; - } else { - from = minimum(subMap.backingMap.root); - fromIndex = from != null ? from.left_idx : 0; - } - if (!subMap.hasEnd) { - return new UnboundedKeyIterator<>(subMap.backingMap, from, - from == null ? 0 : from.right_idx - fromIndex); - } - subMap.setLastKey(); - Node to = subMap.lastKeyNode; - int toIndex = subMap.lastKeyIndex; - return new BoundedKeyIterator<>(from, - from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to, - to == null ? 0 : to.right_idx - toIndex); - } - } - - static class SubMapValuesCollection extends TAbstractCollection { - SubMap subMap; - - public SubMapValuesCollection(SubMap subMap) { - this.subMap = subMap; - } - - @Override - public boolean isEmpty() { - return subMap.isEmpty(); - } - - @Override - public TIterator iterator() { - Node from; - int fromIndex; - if (subMap.hasStart) { - subMap.setFirstKey(); - from = subMap.firstKeyNode; - fromIndex = subMap.firstKeyIndex; - } else { - from = minimum(subMap.backingMap.root); - fromIndex = from != null ? from.left_idx : 0; - } - if (!subMap.hasEnd) { - return new UnboundedValueIterator<>(subMap.backingMap, from, - from == null ? 0 : from.right_idx - fromIndex); - } - subMap.setLastKey(); - Node to = subMap.lastKeyNode; - int toIndex = subMap.lastKeyIndex; - return new BoundedValueIterator<>(from, - from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to, - to == null ? 0 : to.right_idx - toIndex); - } - - @Override - public int size() { - return subMap.size(); - } - } - - public TTreeMap() { - } + TreeNode root; + private TComparator comparator; + private TComparator originalComparator; + private int modCount = 0; public TTreeMap(TComparator comparator) { + this.originalComparator = comparator; + if (comparator == null) { + comparator = new TComparator() { + @SuppressWarnings("unchecked") @Override public int compare(Object o1, Object o2) { + return o1 != null ? ((TComparable)o1).compareTo(o2) : + ((TComparable)o2).compareTo(o1); + } + }; + } this.comparator = comparator; } - public TTreeMap(TMap map) { - putAll(map); + @Override + public V get(Object key) { + TreeNode node = findNode(key); + return node != null ? node.value : null; } - public TTreeMap(TSortedMap map) { - this(map.comparator()); - Node lastNode = null; - TIterator> it = map.entrySet().iterator(); - while (it.hasNext()) { - Entry entry = it.next(); - lastNode = addToLast(lastNode, entry.getKey(), entry.getValue()); - } + @Override + public V put(K key, V value) { + root = getOrCreateNode(root, key); + TreeNode node = findNode(key); + V old = node.value; + node.value = value; + modCount++; + return old; } - Node addToLast(Node last, K key, V value) { - if (last == null) { - root = last = createNode(key, value); - size = 1; - } else if (last.size == Node.NODE_SIZE) { - Node newNode = createNode(key, value); - attachToRight(last, newNode); - balance(newNode); - size++; - last = newNode; - } else { - appendFromRight(last, key, value); - size++; + @Override + public V remove(Object key) { + TreeNode node = findNode(key); + if (node == null) { + return null; } - return last; + root = deleteNode(root, key); + modCount++; + return node.value; } @Override public void clear() { root = null; - size = 0; modCount++; } - @SuppressWarnings("unchecked") - @Rename("clone") - public TObject clone0() { - try { - TTreeMap clone = (TTreeMap) super.clone(); - if (root != null) { - clone.root = root.clone(null); - // restore prev/next chain - Node node = minimum(clone.root); - while (true) { - Node nxt = successor(node); - if (nxt == null) { - break; - } - nxt.prev = node; - node.next = nxt; - node = nxt; - } - } - return clone; - } catch (TCloneNotSupportedException e) { - return null; - } - } - - static private Node successor(Node x) { - if (x.right != null) { - return minimum(x.right); - } - Node y = x.parent; - while (y != null && x == y.right) { - x = y; - y = y.parent; - } - return y; - } - @Override - public TComparator comparator() { - return comparator; + public boolean isEmpty() { + return root == null; } @Override public boolean containsKey(Object key) { - @SuppressWarnings("unchecked") - TComparable object = comparator == null ? toComparable((K) key) : null; - @SuppressWarnings("unchecked") - K keyK = (K)key; - Node node = root; - while (node != null) { - K[] keys = node.keys; - int left_idx = node.left_idx; - int result = cmp(object, keyK, keys[left_idx]); - if (result < 0) { - node = node.left; - } else if (result == 0) { - return true; - } else { - int right_idx = node.right_idx; - if (left_idx != right_idx) { - result = cmp(object, keyK, keys[right_idx]); - } - if (result > 0) { - node = node.right; - } else if (result == 0) { - return true; - } else { /*search in node*/ - int low = left_idx + 1, mid = 0, high = right_idx - 1; - while (low <= high) { - mid = (low + high) >>> 1; - result = cmp(object, keyK, keys[mid]); - if (result > 0) { - low = mid + 1; - } else if (result == 0) { - return true; - } else { - high = mid - 1; - } - } - return false; - } - } - } - return false; + return findNode(key) != null; } - @Override - public boolean containsValue(Object value) { + TreeNode findNode(Object key) { + TreeNode node = root; + while (node != null) { + @SuppressWarnings("unchecked") + int cmp = comparator.compare((K)key, node.key); + if (cmp == 0) { + return node; + } else if (cmp < 0) { + node = node.left; + } else { + node = node.right; + } + } + return null; + } + + private TreeNode getOrCreateNode(TreeNode root, K key) { if (root == null) { - return false; + return new TreeNode(key); } - Node node = minimum(root); - if (value != null) { - while (node != null) { - int to = node.right_idx; - V[] values = node.values; - for (int i = node.left_idx; i <= to; i++) { - if (value.equals(values[i])) { - return true; - } - } - node = node.next; - } + int cmp = comparator.compare(key, root.key); + if (cmp == 0) { + return root; + } else if (cmp < 0) { + root.left = getOrCreateNode(root.left, key); } else { - while (node != null) { - int to = node.right_idx; - V[] values = node.values; - for (int i = node.left_idx; i <= to; i++) { - if (values[i] == null) { - return true; - } - } - node = node.next; - } + root.right = getOrCreateNode(root.right, key); } - return false; + return root.balance(); + } + + private TreeNode deleteNode(TreeNode root, Object key) { + if (root == null) { + return null; + } + @SuppressWarnings("unchecked") + int cmp = comparator.compare((K)key, root.key); + if (cmp < 0) { + root.left = deleteNode(root.left, key); + } else if (cmp > 0) { + root.right = deleteNode(root.right, key); + } else if (root.right == null) { + return root.left; + } else { + TreeNode left = root.left; + TreeNode right = root.right; + TreeNode min = right; + Object[] pathToMin = new Object[right.height]; + int minDepth = 0; + while (min.left != null) { + pathToMin[minDepth++] = min; + min = min.left; + } + right = min.right; + while (minDepth >= 0) { + @SuppressWarnings("unchecked") + TreeNode node = (TreeNode)pathToMin[--minDepth]; + node.left = right; + right = node; + node.balance(); + } + min.right = right; + min.left = left; + root = min; + } + return root.balance(); } @Override public TSet> entrySet() { - if (entrySet == null) { - entrySet = new TAbstractSet>() { - @Override - public int size() { - return size; - } + return new EntrySet(new Object[0], null); + } - @Override - public void clear() { - TTreeMap.this.clear(); - } + @Override + public TComparator comparator() { + return originalComparator; + } - @SuppressWarnings("unchecked") - @Override - public boolean contains(Object object) { - if (object instanceof Entry) { - Entry entry = (Entry) object; - K key = entry.getKey(); - Object v1 = TTreeMap.this.get(key), v2 = entry.getValue(); - return v1 == null ? ( v2 == null && TTreeMap.this.containsKey(key) ) : v1.equals(v2); - } - return false; - } + @Override + public TSortedMap subMap(K fromKey, K toKey) { + return null; + } - @Override - public boolean remove(Object object) { - if (contains(object)) { - @SuppressWarnings("unchecked") - Entry entry = (Entry) object; - K key = entry.getKey(); - TTreeMap.this.remove(key); - return true; - } - return false; - } + @Override + public TSortedMap headMap(K toKey) { + return null; + } - @Override - public TIterator> iterator() { - return new UnboundedEntryIterator<>(TTreeMap.this); - } - }; - } - return entrySet; + @Override + public TSortedMap tailMap(K fromKey) { + return null; } @Override public K firstKey() { - if (root != null) { - Node node = minimum(root); - return node.keys[node.left_idx]; - } - throw new TNoSuchElementException(); - } - - - @Override - public V get(Object key) { - @SuppressWarnings("unchecked") - TComparable object = comparator == null ? toComparable((K) key) : null; - @SuppressWarnings("unchecked") - K keyK = (K) key; - Node node = root; - while (node != null) { - K[] keys = node.keys; - int left_idx = node.left_idx; - int result = cmp(object, keyK, keys[left_idx]); - if (result < 0) { - node = node.left; - } else if (result == 0) { - return node.values[left_idx]; - } else { - int right_idx = node.right_idx; - if (left_idx != right_idx) { - result = cmp(object, keyK, keys[right_idx]); - } - if (result > 0) { - node = node.right; - } else if (result == 0) { - return node.values[right_idx]; - } else { /*search in node*/ - int low = left_idx + 1, mid = 0, high = right_idx - 1; - while (low <= high) { - mid = (low + high) >>> 1; - result = cmp(object, keyK, keys[mid]); - if (result > 0) { - low = mid + 1; - } else if (result == 0) { - return node.values[mid]; - } else { - high = mid - 1; - } - } - return null; - } - } - } - return null; - } - - private int cmp(TComparable object, K key1, K key2) { - return object != null ? object.compareTo(key2) : comparator.compare(key1, key2); - } - - @Override - public TSortedMap headMap(K endKey) { - // Check for errors - if (comparator == null) { - toComparable(endKey).compareTo(endKey); - } else { - comparator.compare(endKey, endKey); - } - return new SubMap<>(this, endKey); - } - - @Override - public TSet keySet() { - if (cachedKeySet == null) { - cachedKeySet = new TAbstractSet() { - @Override - public boolean contains(Object object) { - return TTreeMap.this.containsKey(object); - } - - @Override - public int size() { - return TTreeMap.this.size; - } - - @Override - public void clear() { - TTreeMap.this.clear(); - } - - @Override - public boolean remove(Object object) { - if (contains(object)) { - TTreeMap.this.remove(object); - return true; - } - return false; - } - - @Override - public TIterator iterator() { - return new UnboundedKeyIterator<>(TTreeMap.this); - } - }; - } - return cachedKeySet; + return firstEntry().key; } @Override public K lastKey() { - if (root != null) { - Node node = maximum(root); - return node.keys[node.right_idx]; - } - throw new TNoSuchElementException(); + return lastEntry().key; } - static Node minimum(Node x) { - if (x == null) { - return null; + private TreeNode firstEntry() { + if (isEmpty()) { + throw new TNoSuchElementException(); } - while (x.left != null) { - x = x.left; + TreeNode node = root; + while (node.left != null) { + node = node.left; } - return x; - } - - static Node maximum(Node x) { - if (x == null) { - return null; - } - while (x.right != null) { - x = x.right; - } - return x; - } - - @Override - public V put(K key, V value) { - if (root == null) { - root = createNode(key, value); - size = 1; - modCount++; - return null; - } - TComparable object = comparator == null ? toComparable(key) : null; - K keyK = key; - Node node = root; - Node prevNode = null; - int result = 0; - while (node != null) { - prevNode = node; - K[] keys = node.keys; - int left_idx = node.left_idx; - result = cmp(object, keyK, keys[left_idx]); - if (result < 0) { - node = node.left; - } else if (result == 0) { - V res = node.values[left_idx]; - node.values[left_idx] = value; - return res; - } else { - int right_idx = node.right_idx; - if (left_idx != right_idx) { - result = cmp(object, keyK, keys[right_idx]); - } - if (result > 0) { - node = node.right; - } else if (result == 0) { - V res = node.values[right_idx]; - node.values[right_idx] = value; - return res; - } else { /*search in node*/ - int low = left_idx + 1, mid = 0, high = right_idx - 1; - while (low <= high) { - mid = (low + high) >>> 1; - result = cmp(object, keyK, keys[mid]); - if (result > 0) { - low = mid + 1; - } else if (result == 0) { - V res = node.values[mid]; - node.values[mid] = value; - return res; - } else { - high = mid - 1; - } - } - result = low; - break; - } - } - } /* while */ -/* - if(node == null) { - if(prevNode==null) { - - case of empty Tree - } else { - result < 0 - prevNode.left==null - attach here - result > 0 - prevNode.right==null - attach here - } - } else { - insert into node. - result - index where it should be inserted. - } - */ - size++; - modCount++; - if (node == null) { - if (prevNode == null) { - // case of empty Tree - root = createNode(key, value); - } else if (prevNode.size < Node.NODE_SIZE) { - // there is a place for insert - if (result < 0) { - appendFromLeft(prevNode, key, value); - } else { - appendFromRight(prevNode, key, value); - } - } else { - // create and link - Node newNode = createNode(key, value); - if (result < 0) { - attachToLeft(prevNode, newNode); - } else { - attachToRight(prevNode, newNode); - } - balance(newNode); - } - } else { - // insert into node. - // result - index where it should be inserted. - if (node.size < Node.NODE_SIZE) { // insert and ok - int left_idx = node.left_idx; - int right_idx = node.right_idx; - if (left_idx == 0 || ((right_idx != Node.NODE_SIZE - 1) && (right_idx - result <= result - left_idx))) { - int right_idxPlus1 = right_idx + 1; - System.arraycopy(node.keys, result, node.keys, result + 1, right_idxPlus1 - result); - System.arraycopy(node.values, result, node.values, result + 1, right_idxPlus1 - result); - node.right_idx = right_idxPlus1; - node.keys[result] = key; - node.values[result] = value; - } else { - int left_idxMinus1 = left_idx - 1; - System.arraycopy(node.keys, left_idx, node.keys, left_idxMinus1, result - left_idx); - System.arraycopy(node.values, left_idx, node.values, left_idxMinus1, result - left_idx); - node.left_idx = left_idxMinus1; - node.keys[result - 1] = key; - node.values[result - 1] = value; - } - node.size++; - } else { - // there are no place here - // insert and push old pair - Node previous = node.prev; - Node nextNode = node.next; - boolean removeFromStart; - boolean attachFromLeft = false; - Node attachHere = null; - if (previous == null) { - if (nextNode != null && nextNode.size < Node.NODE_SIZE) { - // move last pair to next - removeFromStart = false; - } else { - // next node doesn't exist or full - // left==null - // drop first pair to new node from left - removeFromStart = true; - attachFromLeft = true; - attachHere = node; - } - } else if (nextNode == null) { - if (previous.size < Node.NODE_SIZE) { - // move first pair to prev - removeFromStart = true; - } else { - // right == null; - // drop last pair to new node from right - removeFromStart = false; - attachFromLeft = false; - attachHere = node; - } - } else { - if (previous.size < Node.NODE_SIZE) { - if (nextNode.size < Node.NODE_SIZE) { - // choose prev or next for moving - removeFromStart = previous.size < nextNode.size; - } else { - // move first pair to prev - removeFromStart = true; - } - } else { - if (nextNode.size < Node.NODE_SIZE) { - // move last pair to next - removeFromStart = false; - } else { - // prev & next are full - // if node.right!=null then node.next.left==null - // if node.left!=null then node.prev.right==null - if (node.right == null) { - attachHere = node; - attachFromLeft = false; - removeFromStart = false; - } else { - attachHere = nextNode; - attachFromLeft = true; - removeFromStart = false; - } - } - } - } - K movedKey; - V movedValue; - if (removeFromStart) { - // node.left_idx == 0 - movedKey = node.keys[0]; - movedValue = node.values[0]; - int resMunus1 = result - 1; - System.arraycopy(node.keys, 1, node.keys, 0, resMunus1); - System.arraycopy(node.values, 1, node.values, 0, resMunus1); - node.keys [resMunus1] = key; - node.values[resMunus1] = value; - } else { - // node.right_idx == Node.NODE_SIZE - 1 - movedKey = node.keys[Node.NODE_SIZE - 1]; - movedValue = node.values[Node.NODE_SIZE - 1]; - System.arraycopy(node.keys, result, node.keys, result + 1, Node.NODE_SIZE - 1 - result); - System.arraycopy(node.values, result, node.values, result + 1, Node.NODE_SIZE - 1 - result); - node.keys[result] = key; - node.values[result] = value; - } - if (attachHere == null) { - if (removeFromStart) { - appendFromRight(previous, movedKey, movedValue); - } else { - appendFromLeft(nextNode, movedKey, movedValue); - } - } else { - Node newNode = createNode(movedKey, movedValue); - if (attachFromLeft) { - attachToLeft(attachHere, newNode); - } else { - attachToRight(attachHere, newNode); - } - balance(newNode); - } - } - } - return null; - } - - private void appendFromLeft(Node node, K keyObj, V value) { - if (node.left_idx == 0) { - int new_right = node.right_idx + 1; - System.arraycopy(node.keys, 0, node.keys, 1, new_right); - System.arraycopy(node.values, 0, node.values, 1, new_right); - node.right_idx = new_right; - } else { - node.left_idx--; - } - node.size++; - node.keys[node.left_idx] = keyObj; - node.values[node.left_idx] = value; - } - - private void attachToLeft(Node node, Node newNode) { - newNode.parent = node; - // node.left==null - attach here - node.left = newNode; - Node predecessor = node.prev; - newNode.prev = predecessor; - newNode.next = node; - if (predecessor != null) { - predecessor.next = newNode; - } - node.prev = newNode; - } - - /* add pair into node; existence free room in the node should be checked - * before call - */ - private void appendFromRight(Node node, K keyObj, V value) { - if (node.right_idx == Node.NODE_SIZE - 1) { - int left_idx = node.left_idx; - int left_idxMinus1 = left_idx - 1; - System.arraycopy(node.keys, left_idx, node.keys, left_idxMinus1, Node.NODE_SIZE - left_idx); - System.arraycopy(node.values, left_idx, node.values, left_idxMinus1, Node.NODE_SIZE - left_idx); - node.left_idx = left_idxMinus1; - } else { - node.right_idx++; - } - node.size++; - node.keys[node.right_idx] = keyObj; - node.values[node.right_idx] = value; - } - - private void attachToRight(Node node, Node newNode) { - newNode.parent = node; - // - node.right==null - attach here - node.right = newNode; - newNode.prev = node; - Node successor = node.next; - newNode.next = successor; - if (successor != null) { - successor.prev = newNode; - } - node.next = newNode; - } - - private Node createNode(K keyObj, V value) { - Node node = new Node<>(); - node.keys[0] = keyObj; - node.values[0] = value; - node.left_idx = 0; - node.right_idx = 0; - node.size = 1; return node; } - void balance(Node x) { - Node y; - x.color = true; - while (x != root && x.parent.color) { - if (x.parent == x.parent.parent.left) { - y = x.parent.parent.right; - if (y != null && y.color) { - x.parent.color = false; - y.color = false; - x.parent.parent.color = true; - x = x.parent.parent; - } else { - if (x == x.parent.right) { - x = x.parent; - leftRotate(x); - } - x.parent.color = false; - x.parent.parent.color = true; - rightRotate(x.parent.parent); - } - } else { - y = x.parent.parent.left; - if (y != null && y.color) { - x.parent.color = false; - y.color = false; - x.parent.parent.color = true; - x = x.parent.parent; - } else { - if (x == x.parent.left) { - x = x.parent; - rightRotate(x); - } - x.parent.color = false; - x.parent.parent.color = true; - leftRotate(x.parent.parent); - } - } + private TreeNode lastEntry() { + if (isEmpty()) { + throw new TNoSuchElementException(); } - root.color = false; - } - - private void rightRotate(Node x) { - Node y = x.left; - x.left = y.right; - if (y.right != null) { - y.right.parent = x; + TreeNode node = root; + while (node.left != null) { + node = node.left; } - y.parent = x.parent; - if (x.parent == null) { - root = y; - } else { - if (x == x.parent.right) { - x.parent.right = y; - } else { - x.parent.left = y; - } - } - y.right = x; - x.parent = y; - } - - - private void leftRotate(Node x) { - Node y = x.right; - x.right = y.left; - if (y.left != null) { - y.left.parent = x; - } - y.parent = x.parent; - if (x.parent == null) { - root = y; - } else { - if (x == x.parent.left) { - x.parent.left = y; - } else { - x.parent.right = y; - } - } - y.left = x; - x.parent = y; - } - - @Override - public void putAll(TMap map) { - super.putAll(map); - } - - @Override - public V remove(Object key) { - if (size == 0) { - return null; - } - @SuppressWarnings("unchecked") - TComparable object = comparator == null ? toComparable((K) key) : null; - @SuppressWarnings("unchecked") - K keyK = (K) key; - Node node = root; - while (node != null) { - K[] keys = node.keys; - int left_idx = node.left_idx; - int result = cmp(object, keyK, keys[left_idx]); - if (result < 0) { - node = node.left; - } else if (result == 0) { - V value = node.values[left_idx]; - removeLeftmost(node); - return value; - } else { - int right_idx = node.right_idx; - if (left_idx != right_idx) { - result = cmp(object, keyK, keys[right_idx]); - } - if (result > 0) { - node = node.right; - } else if (result == 0) { - V value = node.values[right_idx]; - removeRightmost(node); - return value; - } else { /*search in node*/ - int low = left_idx + 1, mid = 0, high = right_idx - 1; - while (low <= high) { - mid = (low + high) >>> 1; - result = cmp(object, keyK, keys[mid]); - if (result > 0) { - low = mid + 1; - } else if (result == 0) { - V value = node.values[mid]; - removeMiddleElement(node, mid); - return value; - } else { - high = mid - 1; - } - } - return null; - } - } - } - return null; - } - - void removeLeftmost(Node node) { - int index = node.left_idx; - if (node.size == 1) { - deleteNode(node); - } else if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) { - // move all to prev node and kill it - Node prev = node.prev; - int size = node.right_idx - index; - System.arraycopy(node.keys, index + 1, prev.keys, prev.right_idx + 1, size); - System.arraycopy(node.values, index + 1, prev.values, prev.right_idx + 1, size); - prev.right_idx += size; - prev.size += size; - deleteNode(node); - } else if (node.next != null && (node.next.left_idx) > node.size) { - // move all to next node and kill it - Node next = node.next; - int size = node.right_idx - index; - int next_new_left = next.left_idx - size; - next.left_idx = next_new_left; - System.arraycopy(node.keys, index + 1, next.keys, next_new_left, size); - System.arraycopy(node.values, index + 1, next.values, next_new_left, size); - next.size += size; - deleteNode(node); - } else { - node.keys[index] = null; - node.values[index] = null; - node.left_idx++; - node.size--; - Node prev = node.prev; - if (prev != null && prev.size == 1) { - node.size++; - node.left_idx--; - node.keys [node.left_idx] = prev.keys [prev.left_idx]; - node.values[node.left_idx] = prev.values[prev.left_idx]; - deleteNode(prev); - } - } - modCount++; - size--; - } - - void removeRightmost(Node node) { - int index = node.right_idx; - if (node.size == 1) { - deleteNode(node); - } else if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) { - // move all to prev node and kill it - Node prev = node.prev; - int left_idx = node.left_idx; - int size = index - left_idx; - System.arraycopy(node.keys, left_idx, prev.keys, prev.right_idx + 1, size); - System.arraycopy(node.values, left_idx, prev.values, prev.right_idx + 1, size); - prev.right_idx += size; - prev.size += size; - deleteNode(node); - } else if (node.next != null && (node.next.left_idx) > node.size) { - // move all to next node and kill it - Node next = node.next; - int left_idx = node.left_idx; - int size = index - left_idx; - int next_new_left = next.left_idx - size; - next.left_idx = next_new_left; - System.arraycopy(node.keys, left_idx, next.keys, next_new_left, size); - System.arraycopy(node.values, left_idx, next.values, next_new_left, size); - next.size += size; - deleteNode(node); - } else { - node.keys[index] = null; - node.values[index] = null; - node.right_idx--; - node.size--; - Node next = node.next; - if (next != null && next.size == 1) { - node.size++; - node.right_idx++; - node.keys[node.right_idx] = next.keys[next.left_idx]; - node.values[node.right_idx] = next.values[next.left_idx]; - deleteNode(next); - } - } - modCount++; - size--; - } - - void removeMiddleElement(Node node, int index) { - // this function is called iff index if some middle element; - // so node.left_idx < index < node.right_idx - // condition above assume that node.size > 1 - if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) { - // move all to prev node and kill it - Node prev = node.prev; - int left_idx = node.left_idx; - int size = index - left_idx; - System.arraycopy(node.keys, left_idx, prev.keys, prev.right_idx + 1, size); - System.arraycopy(node.values, left_idx, prev.values, prev.right_idx + 1, size); - prev.right_idx += size; - size = node.right_idx - index; - System.arraycopy(node.keys, index + 1, prev.keys, prev.right_idx + 1, size); - System.arraycopy(node.values, index + 1, prev.values, prev.right_idx + 1, size); - prev.right_idx += size; - prev.size += (node.size - 1); - deleteNode(node); - } else if (node.next != null && (node.next.left_idx) > node.size) { - // move all to next node and kill it - Node next = node.next; - int left_idx = node.left_idx; - int next_new_left = next.left_idx - node.size + 1; - next.left_idx = next_new_left; - int size = index - left_idx; - System.arraycopy(node.keys, left_idx, next.keys, next_new_left, size); - System.arraycopy(node.values, left_idx, next.values, next_new_left, size); - next_new_left += size; - size = node.right_idx - index; - System.arraycopy(node.keys, index + 1, next.keys, next_new_left, size); - System.arraycopy(node.values, index + 1, next.values, next_new_left, size); - next.size += (node.size - 1); - deleteNode(node); - } else { - int moveFromRight = node.right_idx - index; - int left_idx = node.left_idx; - int moveFromLeft = index - left_idx ; - if (moveFromRight <= moveFromLeft) { - System.arraycopy(node.keys, index + 1, node.keys, index, moveFromRight); - System.arraycopy(node.values, index + 1, node.values, index, moveFromRight); - Node next = node.next; - if (next != null && next.size == 1) { - node.keys [node.right_idx] = next.keys [next.left_idx]; - node.values[node.right_idx] = next.values[next.left_idx]; - deleteNode(next); - } else { - node.keys [node.right_idx] = null; - node.values[node.right_idx] = null; - node.right_idx--; - node.size--; - } - } else { - System.arraycopy(node.keys, left_idx , node.keys, left_idx + 1, moveFromLeft); - System.arraycopy(node.values, left_idx , node.values, left_idx + 1, moveFromLeft); - Node prev = node.prev; - if (prev != null && prev.size == 1) { - node.keys [left_idx ] = prev.keys [prev.left_idx]; - node.values[left_idx ] = prev.values[prev.left_idx]; - deleteNode(prev); - } else { - node.keys [left_idx ] = null; - node.values[left_idx ] = null; - node.left_idx++; - node.size--; - } - } - } - modCount++; - size--; - } - - void removeFromIterator(Node node, int index) { - if (node.size == 1) { - // it is safe to delete the whole node here. - // iterator already moved to the next node; - deleteNode(node); - } else { - int left_idx = node.left_idx; - if (index == left_idx) { - Node prev = node.prev; - if (prev != null && prev.size == 1) { - node.keys [left_idx] = prev.keys [prev.left_idx]; - node.values[left_idx] = prev.values[prev.left_idx]; - deleteNode(prev); - } else { - node.keys [left_idx] = null; - node.values[left_idx] = null; - node.left_idx++; - node.size--; - } - } else if (index == node.right_idx) { - node.keys [index] = null; - node.values[index] = null; - node.right_idx--; - node.size--; - } else { - int moveFromRight = node.right_idx - index; - int moveFromLeft = index - left_idx; - if (moveFromRight <= moveFromLeft) { - System.arraycopy(node.keys, index + 1, node.keys, index, moveFromRight ); - System.arraycopy(node.values, index + 1, node.values, index, moveFromRight ); - node.keys [node.right_idx] = null; - node.values[node.right_idx] = null; - node.right_idx--; - node.size--; - } else { - System.arraycopy(node.keys, left_idx, node.keys, left_idx+ 1, moveFromLeft); - System.arraycopy(node.values, left_idx, node.values, left_idx+ 1, moveFromLeft); - node.keys [left_idx] = null; - node.values[left_idx] = null; - node.left_idx++; - node.size--; - } - } - } - modCount++; - size--; - } - - private void deleteNode(Node node) { - if (node.right == null) { - if (node.left != null) { - attachToParent(node, node.left); - } else { - attachNullToParent(node); - } - fixNextChain(node); - } else if(node.left == null) { // node.right != null - attachToParent(node, node.right); - fixNextChain(node); - } else { - // Here node.left!=nul && node.right!=null - // node.next should replace node in tree - // node.next!=null by tree logic. - // node.next.left==null by tree logic. - // node.next.right may be null or non-null - Node toMoveUp = node.next; - fixNextChain(node); - if(toMoveUp.right==null){ - attachNullToParent(toMoveUp); - } else { - attachToParent(toMoveUp, toMoveUp.right); - } - // Here toMoveUp is ready to replace node - toMoveUp.left = node.left; - if (node.left != null) { - node.left.parent = toMoveUp; - } - toMoveUp.right = node.right; - if (node.right != null) { - node.right.parent = toMoveUp; - } - attachToParentNoFixup(node,toMoveUp); - toMoveUp.color = node.color; - } - } - - private void attachToParentNoFixup(Node toDelete, Node toConnect) { - // assert toConnect!=null - Node parent = toDelete.parent; - toConnect.parent = parent; - if (parent == null) { - root = toConnect; - } else if (toDelete == parent.left) { - parent.left = toConnect; - } else { - parent.right = toConnect; - } - } - - private void attachToParent(Node toDelete, Node toConnect) { - // assert toConnect!=null - attachToParentNoFixup(toDelete,toConnect); - if (!toDelete.color) { - fixup(toConnect); - } - } - - private void attachNullToParent(Node toDelete) { - Node parent = toDelete.parent; - if (parent == null) { - root = null; - } else { - if (toDelete == parent.left) { - parent.left = null; - } else { - parent.right = null; - } - if (!toDelete.color) { - fixup(parent); - } - } - } - - private void fixNextChain(Node node) { - if (node.prev != null) { - node.prev.next = node.next; - } - if (node.next != null) { - node.next.prev = node.prev; - } - } - - private void fixup(Node x) { - Node w; - while (x != root && !x.color) { - if (x == x.parent.left) { - w = x.parent.right; - if (w == null) { - x = x.parent; - continue; - } - if (w.color) { - w.color = false; - x.parent.color = true; - leftRotate(x.parent); - w = x.parent.right; - if (w == null) { - x = x.parent; - continue; - } - } - if ((w.left == null || !w.left.color) - && (w.right == null || !w.right.color)) { - w.color = true; - x = x.parent; - } else { - if (w.right == null || !w.right.color) { - w.left.color = false; - w.color = true; - rightRotate(w); - w = x.parent.right; - } - w.color = x.parent.color; - x.parent.color = false; - w.right.color = false; - leftRotate(x.parent); - x = root; - } - } else { - w = x.parent.left; - if (w == null) { - x = x.parent; - continue; - } - if (w.color) { - w.color = false; - x.parent.color = true; - rightRotate(x.parent); - w = x.parent.left; - if (w == null) { - x = x.parent; - continue; - } - } - if ((w.left == null || !w.left.color) - && (w.right == null || !w.right.color)) { - w.color = true; - x = x.parent; - } else { - if (w.left == null || !w.left.color) { - w.right.color = false; - w.color = true; - leftRotate(w); - w = x.parent.left; - } - w.color = x.parent.color; - x.parent.color = false; - w.left.color = false; - rightRotate(x.parent); - x = root; - } - } - } - x.color = false; + return node; } @Override public int size() { - return size; + return root != null ? root.size : 0; } - @Override - public TSortedMap subMap(K startKey, K endKey) { - if (comparator == null) { - if (toComparable(startKey).compareTo(endKey) <= 0) { - return new SubMap<>(startKey, this, endKey); + private class EntrySet extends TAbstractSet> { + private Object[] path; + private TreeNode from; + private TreeNode to; + + @SuppressWarnings("unchecked") + public EntrySet(Object[] path, TreeNode to) { + this.path = path; + this.from = this.path.length > 0 ? (TreeNode)this.path[this.path.length - 1] : null; + this.to = to; + } + + @Override + public int size() { + int size = TTreeMap.this.size(); + if (from != null && from.left != null) { + size -= from.left.size; } - } else { - if (comparator.compare(startKey, endKey) <= 0) { - return new SubMap<>(startKey, this, endKey); + if (to != null) { + size -= 1; + if (to.right != null) { + size -= to.right.size; + } + } + return size; + } + + @Override + public TIterator> iterator() { + return null; + } + } + + private class EntryIterator implements TIterator> { + private int modCount = TTreeMap.this.modCount; + private Object[] path = new Object[root != null ? root.height : 0]; + private TreeNode last; + private TreeNode to; + private int pathLength; + public EntryIterator(Object[] path, TreeNode to) { + TreeNode node = root; + while (node != null) { + path[pathLength++] = node; + node = node.left; } } - throw new TIllegalArgumentException(); - } - - @Override - public TSortedMap tailMap(K startKey) { - // Check for errors - if (comparator == null) { - toComparable(startKey).compareTo(startKey); - } else { - comparator.compare(startKey, startKey); + @Override public boolean hasNext() { + return pathLength > 0; } - return new SubMap<>(startKey, this); - } - - @Override - public TCollection values() { - if (cachedValues == null) { - cachedValues = new TAbstractCollection() { - @Override - public boolean contains(Object object) { - return containsValue(object); + @SuppressWarnings("unchecked") @Override public Entry next() { + if (modCount != TTreeMap.this.modCount) { + throw new TConcurrentModificationException(); + } + if (pathLength == 0) { + throw new TNoSuchElementException(); + } + TreeNode node = (TreeNode)path[--pathLength]; + last = node; + if (node.right != null) { + node = node.right; + while (node != null) { + path[pathLength++] = node; + node = node.left; } - - @Override - public int size() { - return size; - } - - @Override - public void clear() { - TTreeMap.this.clear(); - } - - @Override - public TIterator iterator() { - return new UnboundedValueIterator<>(TTreeMap.this); - } - }; + } + return last; + } + @Override public void remove() { + if (last == null) { + throw new TNoSuchElementException(); + } + deleteNode(root, last); + last = null; } - return cachedValues; } }