Index: modules/luni/src/main/java/java/util/TreeMap.java =================================================================== --- modules/luni/src/main/java/java/util/TreeMap.java (revision 599712) +++ modules/luni/src/main/java/java/util/TreeMap.java (working copy) @@ -27,16 +27,14 @@ * supported, adding and removing. The values can be any objects. The keys can * be any objects which are comparable to each other either using their natural * order or a specified Comparator. - * * @since 1.2 */ -public class TreeMap extends AbstractMap implements - SortedMap, Cloneable, Serializable { +public class TreeMap extends AbstractMap implements SortedMap, Cloneable, + Serializable { + private static final long serialVersionUID = 919286545866124006L; - private static final long serialVersionUID = 919286545866124006L; + transient int size; - transient int size; - transient Entry root; private Comparator comparator; @@ -45,43 +43,50 @@ transient Set> entrySet; - /** - * Entry is an internal class which is used to hold the entries of a - * TreeMap. - */ - static class Entry extends MapEntry { - Entry parent, left, right; + static final int SMALL_LIMIT=127; + transient K[] small_keys; + transient V[] small_values; + transient Entry[] small_entries; + transient int small_left=0; + transient int small_right=-1; - boolean color; + /** + * Entry is an internal class which is used to hold the entries of a + * TreeMap. + */ + static class Entry extends MapEntry { + Entry parent, left, right; - Entry(K key) { - super(key); - } + boolean color; - Entry(K key, V value) { - super(key, value); - } + Entry(K key) { + super(key); + } - @SuppressWarnings("unchecked") + Entry(K key, V value) { + super(key, value); + } + + @SuppressWarnings("unchecked") Entry clone(Entry parent) { - Entry clone = (Entry) super.clone(); - clone.parent = parent; - if (left != null) { + Entry clone = (Entry) super.clone(); + clone.parent = parent; + if (left != null) { clone.left = left.clone(clone); } - if (right != null) { + if (right != null) { clone.right = right.clone(clone); } - return clone; - } - } + return clone; + } + } @SuppressWarnings("unchecked") private static Comparable toComparable(T obj) { - return (Comparable) obj; + return (Comparable)obj; } - private static class AbstractMapIterator { + private static class AbstractMapIterator { TreeMap backingMap; int expectedModCount; TreeMap.Entry node; @@ -110,797 +115,959 @@ throw new ConcurrentModificationException(); } } + } - final void makeNext() { - if (expectedModCount != backingMap.modCount) { - throw new ConcurrentModificationException(); - } else if (node == null) { - throw new NoSuchElementException(); + private static class UnboundedIterator extends AbstractMapIterator { + + public UnboundedIterator(TreeMap treeMap, Entry entry) { + super(treeMap, entry); } - lastNode = node; - node = TreeMap.successor(node); - } - } - private static class UnboundedEntryIterator extends - AbstractMapIterator implements Iterator> { + final void makeNext() { + if (expectedModCount != backingMap.modCount) { + throw new ConcurrentModificationException(); + } else if (node == null) { + throw new NoSuchElementException(); + } + lastNode = node; + node = TreeMap.successor(node); + } - UnboundedEntryIterator(TreeMap map, Entry startNode) { - super(map, startNode); - } + } - UnboundedEntryIterator(TreeMap map) { - super(map, map.root == null ? null : TreeMap.minimum(map.root)); - } + private static class UnboundedEntryIterator extends UnboundedIterator implements Iterator> { - public Map.Entry next() { - makeNext(); - return lastNode; - } - } + UnboundedEntryIterator(TreeMap map, Entry startNode) { + super(map, startNode); + } - static class UnboundedKeyIterator extends AbstractMapIterator - implements Iterator { - public UnboundedKeyIterator(TreeMap treeMap, Entry entry) { - super(treeMap, entry); - } + UnboundedEntryIterator(TreeMap map) { + super(map, map.root == null ? null : TreeMap.minimum(map.root)); + } - public UnboundedKeyIterator(TreeMap map) { - super(map, map.root == null ? null : TreeMap.minimum(map.root)); + public Map.Entry next() { + makeNext(); + return lastNode; + } } - public K next() { - makeNext(); - return lastNode.key; - } - } + static class UnboundedKeyIterator extends UnboundedIterator implements Iterator { + public UnboundedKeyIterator(TreeMap treeMap, Entry entry) { + super(treeMap, entry); + } - static class UnboundedValueIterator extends AbstractMapIterator - implements Iterator { + public UnboundedKeyIterator(TreeMap map) { + super(map, map.root == null ? null : TreeMap.minimum(map.root)); + } - public UnboundedValueIterator(TreeMap treeMap, - Entry startNode) { - super(treeMap, startNode); + public K next() { + makeNext(); + return lastNode.key; + } } - public UnboundedValueIterator(TreeMap map) { - super(map, map.root == null ? null : TreeMap.minimum(map.root)); - } + static class UnboundedValueIterator extends UnboundedIterator implements Iterator { - public V next() { - makeNext(); - return lastNode.value; - } - } + public UnboundedValueIterator(TreeMap treeMap, Entry startNode) { + super(treeMap, startNode); + } - private static class ComparatorBoundedIterator extends - AbstractMapIterator { - private final K endKey; + public UnboundedValueIterator(TreeMap map) { + super(map, map.root == null ? null : TreeMap.minimum(map.root)); + } - private final Comparator cmp; - - ComparatorBoundedIterator(TreeMap map, Entry startNode, - K end) { - super(map, startNode); - endKey = end; - cmp = map.comparator(); + public V next() { + makeNext(); + return lastNode.value; + } } - final void cleanNext() { - if (node != null && cmp.compare(endKey, node.key) <= 0) { - node = null; + private static class BoundedIterator extends AbstractMapIterator { + private final TreeMap.Entry finishNode; + + BoundedIterator(TreeMap map, Entry startNode, Entry finishNode) { + super(map, startNode); + this.finishNode = finishNode; } - } - @Override - public boolean hasNext() { - return (node != null && endKey != null) - && (cmp.compare(node.key, endKey) < 0); + final void makeNext() { + if (expectedModCount != backingMap.modCount) { + throw new ConcurrentModificationException(); + } else if (node == null) { + throw new NoSuchElementException(); + } + lastNode = node; + if(node!=finishNode) { + node = TreeMap.successor(node); + } else { + node = null; + } + } } - } - private static class ComparatorBoundedEntryIterator extends - ComparatorBoundedIterator implements - Iterator> { - ComparatorBoundedEntryIterator(TreeMap map, - Entry startNode, K end) { - super(map, startNode, end); + private static class BoundedEntryIterator extends + BoundedIterator implements Iterator> { + + BoundedEntryIterator(TreeMap map, Entry startNode, Entry finishNode) { + super(map, startNode, finishNode); } public Map.Entry next() { makeNext(); - cleanNext(); return lastNode; } } - private static class ComparatorBoundedKeyIterator extends - ComparatorBoundedIterator implements Iterator { + private static class BoundedKeyIterator extends + BoundedIterator implements Iterator { - ComparatorBoundedKeyIterator(TreeMap map, Entry startNode, - K end) { - super(map, startNode, end); + BoundedKeyIterator(TreeMap map, Entry startNode, Entry finishNode) { + super(map, startNode, finishNode); } public K next() { makeNext(); - cleanNext(); return lastNode.key; } } - private static class ComparatorBoundedValueIterator extends - ComparatorBoundedIterator implements Iterator { + private static class BoundedValueIterator extends + BoundedIterator implements Iterator { - ComparatorBoundedValueIterator(TreeMap map, - Entry startNode, K end) { - super(map, startNode, end); + BoundedValueIterator(TreeMap map, Entry startNode, Entry finishNode) { + super(map, startNode, finishNode); } public V next() { makeNext(); - cleanNext(); return lastNode.value; } } - private static class ComparableBoundedIterator extends - AbstractMapIterator { - private final Comparable endKey; + private static class SmallMapIterator { + TreeMap backingMap; + int expectedModCount; + int index; + int lastIndex; + int endIndex; - public ComparableBoundedIterator(TreeMap treeMap, - Entry entry, Comparable endKey) { - super(treeMap, entry); - this.endKey = endKey; + SmallMapIterator(TreeMap map, int startIndex, int endIndex) { + backingMap = map; + expectedModCount = map.modCount; + index = startIndex; + this.endIndex = endIndex; } - final void cleanNext() { - if ((node != null) && (endKey.compareTo(node.key) <= 0)) { - node = null; - } + public boolean hasNext() { + return index<=endIndex; } - @Override - public boolean hasNext() { - return (node != null) && (endKey.compareTo(node.key) > 0); + final void makeNext() { + if (expectedModCount != backingMap.modCount) { + throw new ConcurrentModificationException(); + } else if (index>endIndex) { + throw new NoSuchElementException(); + } + lastIndex = index++; + } + + final public void remove() { + if (expectedModCount == backingMap.modCount) { + if (lastIndex != -1) { + if(backingMap.smallDelete(lastIndex)) { + endIndex--; + index--; + } + lastIndex = -1; + expectedModCount++; + } else { + throw new IllegalStateException(); + } + } else { + throw new ConcurrentModificationException(); + } } } - private static class ComparableBoundedEntryIterator extends - ComparableBoundedIterator implements - Iterator> { + private static class SmallEntryIterator extends + SmallMapIterator implements Iterator> { - ComparableBoundedEntryIterator(TreeMap map, - Entry startNode, Comparable end) { - super(map, startNode, end); - } + SmallEntryIterator(TreeMap map, int startIndex, int endIndex) { + super(map, startIndex, endIndex); + } - public Map.Entry next() { - makeNext(); - cleanNext(); - return lastNode; - } + public Map.Entry next() { + makeNext(); + if(backingMap.small_entries==null) { + backingMap.small_entries = (Entry[])new Entry[backingMap.small_keys.length]; + } + if(backingMap.small_entries[lastIndex]==null) { + backingMap.small_entries[lastIndex]=new Entry(backingMap.small_keys[lastIndex],backingMap.small_values[lastIndex]); + } + return backingMap.small_entries[lastIndex]; + } + } - } + private static class SmallKeyIterator extends + SmallMapIterator implements Iterator { - private static class ComparableBoundedKeyIterator extends - ComparableBoundedIterator implements Iterator { - - ComparableBoundedKeyIterator(TreeMap map, Entry startNode, - Comparable end) { - super(map, startNode, end); + SmallKeyIterator(TreeMap map, int startIndex, int endIndex) { + super(map, startIndex, endIndex); } public K next() { makeNext(); - cleanNext(); - return lastNode.key; + return backingMap.small_keys[lastIndex]; } } - private static class ComparableBoundedValueIterator extends - ComparableBoundedIterator implements Iterator { + private static class SmallValueIterator extends + SmallMapIterator implements Iterator { - ComparableBoundedValueIterator(TreeMap map, - Entry startNode, Comparable end) { - super(map, startNode, end); + SmallValueIterator(TreeMap map, int startIndex, int endIndex) { + super(map, startIndex, endIndex); } public V next() { makeNext(); - cleanNext(); - return lastNode.value; + return backingMap.small_values[lastIndex]; } } - static final class SubMap extends AbstractMap implements - SortedMap, Serializable { - private static final long serialVersionUID = -6520786458950516097L; + static final class SubMap extends AbstractMap implements SortedMap, Serializable { + private static final long serialVersionUID = -6520786458950516097L; - private TreeMap backingMap; + private TreeMap backingMap; - boolean hasStart, hasEnd; + boolean hasStart, hasEnd; - K startKey, endKey; + K startKey, endKey; - transient Set> entrySet = null; + transient Set> entrySet = null; + transient int firstEntryModCount = -1; + transient int lastEntryModCount = -1; + transient TreeMap.Entry firstEntry; + transient TreeMap.Entry lastEntry; - SubMap(K start, TreeMap map) { - backingMap = map; - hasStart = true; - startKey = start; - } + SubMap(K start, TreeMap map) { + backingMap = map; + hasStart = true; + startKey = start; + } - SubMap(K start, TreeMap map, K end) { - backingMap = map; - hasStart = hasEnd = true; - startKey = start; - endKey = end; - } - - SubMap(TreeMap map, K end) { - backingMap = map; - hasEnd = true; - endKey = end; - } - - private void checkRange(K key) { - Comparator cmp = backingMap.comparator; - if (cmp == null) { - Comparable object = toComparable(key); - if (hasStart && object.compareTo(startKey) < 0) { - throw new IllegalArgumentException(); - } - if (hasEnd && object.compareTo(endKey) > 0) { - throw new IllegalArgumentException(); - } - } else { - if (hasStart - && backingMap.comparator().compare(key, startKey) < 0) { - throw new IllegalArgumentException(); - } - if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) { - throw new IllegalArgumentException(); - } + SubMap(K start, TreeMap map, K end) { + backingMap = map; + hasStart = hasEnd = true; + startKey = start; + endKey = end; } - } - private boolean isInRange(K key) { - Comparator cmp = backingMap.comparator; - if (cmp == null) { - Comparable 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; - } + SubMap(TreeMap map, K end) { + backingMap = map; + hasEnd = true; + endKey = end; } - return true; - } - private boolean checkUpperBound(K key) { - if (hasEnd) { + private void checkRange(K key) { Comparator cmp = backingMap.comparator; if (cmp == null) { - return (toComparable(key).compareTo(endKey) < 0); + Comparable object = toComparable(key); + if (hasStart && object.compareTo(startKey) < 0) { + throw new IllegalArgumentException(); + } + if (hasEnd && object.compareTo(endKey) > 0) { + throw new IllegalArgumentException(); + } + } else { + if (hasStart + && backingMap.comparator().compare(key, startKey) < 0) { + throw new IllegalArgumentException(); + } + if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) { + throw new IllegalArgumentException(); + } } - return (cmp.compare(key, endKey) < 0); } - return true; - } - private boolean checkLowerBound(K key) { - if (hasStart) { + private boolean isInRange(K key) { Comparator cmp = backingMap.comparator; if (cmp == null) { - return (toComparable(key).compareTo(startKey) >= 0); + Comparable 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 (cmp.compare(key, startKey) >= 0); + return true; } - return true; - } - public Comparator comparator() { - return backingMap.comparator(); - } + private boolean checkUpperBound(K key) { + if (hasEnd) { + Comparator cmp = backingMap.comparator; + if (cmp == null) { + return (toComparable(key).compareTo(endKey) < 0); + } + return (cmp.compare(key, endKey) < 0); + } + return true; + } - @SuppressWarnings("unchecked") - @Override - public boolean containsKey(Object key) { - if (isInRange((K) key)) { - return backingMap.containsKey(key); + private boolean checkLowerBound(K key) { + if (hasStart) { + Comparator cmp = backingMap.comparator; + if (cmp == null) { + return (toComparable(key).compareTo(startKey) >= 0); + } + return (cmp.compare(key, startKey) >= 0); + } + return true; } - return false; - } - @Override - public Set> entrySet() { - if (entrySet == null) { - entrySet = new SubMapEntrySet(this); + public Comparator comparator() { + return backingMap.comparator(); } - return entrySet; - } - public K firstKey() { - TreeMap.Entry node = firstEntry(); - if (node != null) { - return node.key; + @SuppressWarnings("unchecked") + @Override + public boolean containsKey(Object key) { + if (isInRange((K)key)) { + return backingMap.containsKey(key); + } + return false; } - throw new NoSuchElementException(); - } - TreeMap.Entry firstEntry() { - if (!hasStart) { - TreeMap.Entry root = backingMap.root; - return (root == null) ? null : minimum(backingMap.root); + @Override + public Set> entrySet() { + if(entrySet==null) { + entrySet = new SubMapEntrySet(this); + } + return entrySet; } - TreeMap.Entry node = backingMap.findAfter(startKey); - if (node != null && checkUpperBound(node.key)) { + + public K firstKey() { + if(backingMap.size>0) { + if(backingMap.isSmall()) { + if(!hasStart) { + K kres = backingMap.small_keys[backingMap.small_left]; + if(checkUpperBound(kres)) { + return kres; + } + + } else { + int idx = backingMap.smallFindAfter(startKey); + if(idx>=backingMap.small_left && idx <=backingMap.small_right){ + K kres = backingMap.small_keys[idx]; + if(checkUpperBound(kres)) { + return kres; + } + } + } + } else { + TreeMap.Entry node = firstEntry(); + if (node != null ) { + return node.key; + } + } + } + throw new NoSuchElementException(); + } + + TreeMap.Entry firstEntry() { + if(firstEntryModCount == backingMap.modCount) { + return firstEntry; + } + TreeMap.Entry node; + if (!hasStart) { + TreeMap.Entry root = backingMap.root; + node = (root == null) ? null : minimum(root); + } else { + node = backingMap.findAfter(startKey); + } + if (node != null && !checkUpperBound(node.key)) { + node = null; + } + firstEntry = node; + firstEntryModCount = backingMap.modCount; return node; } - return null; - } - @SuppressWarnings("unchecked") - @Override - public V get(Object key) { - if (isInRange((K) key)) { - return backingMap.get(key); + @SuppressWarnings("unchecked") + @Override + public V get(Object key) { + if (isInRange((K)key)) { + return backingMap.get(key); + } + return null; } - return null; - } - public SortedMap headMap(K endKey) { - checkRange(endKey); - if (hasStart) { - return new SubMap(startKey, backingMap, endKey); + public SortedMap headMap(K endKey) { + checkRange(endKey); + if (hasStart) { + return new SubMap(startKey, backingMap, endKey); + } + return new SubMap(backingMap, endKey); } - return new SubMap(backingMap, endKey); - } - @Override - public boolean isEmpty() { - if (hasStart) { - TreeMap.Entry node = backingMap.findAfter(startKey); - return node == null || !checkUpperBound(node.key); + @Override + public boolean isEmpty() { + if (!hasStart) { + return firstEntry()==null; + } else { + return lastEntry()==null; + } } - return backingMap.findBefore(endKey) == null; - } - @Override - public Set keySet() { - if (keySet == null) { - keySet = new SubMapKeySet(this); + @Override + public Set keySet() { + if (keySet == null) { + keySet = new SubMapKeySet(this); + } + return keySet; } - return keySet; - } - public K lastKey() { - if (!hasEnd) { - return backingMap.lastKey(); + public K lastKey() { + if (backingMap.size > 0) { + if (backingMap.isSmall()) { + if (!hasEnd) { + K kres = backingMap.small_keys[backingMap.small_right]; + if(checkLowerBound(kres)) { + return kres; + } + } else { + int idx = backingMap.smallFindBefore(endKey); + if (idx>=backingMap.small_left && idx <= backingMap.small_right) { + K kres = backingMap.small_keys[idx] ; + if(checkLowerBound(kres)) { + return kres; + } + } + } + } else { + TreeMap.Entry node = lastEntry(); + if (node != null) { + return node.key; + } + } + } + throw new NoSuchElementException(); } - TreeMap.Entry node = backingMap.findBefore(endKey); - if (node != null && checkLowerBound(node.key)) { - return node.key; + + TreeMap.Entry lastEntry() { + if(lastEntryModCount == backingMap.modCount) { + return lastEntry; + } + TreeMap.Entry node; + if (!hasEnd) { + TreeMap.Entry root = backingMap.root; + node = (root == null) ? null : maximum(root); + } else { + node = backingMap.findBefore(endKey); + } + if (node != null && !checkLowerBound(node.key)) { + node = null; + } + lastEntry = node; + lastEntryModCount = backingMap.modCount; + return node; } - throw new NoSuchElementException(); - } - @Override - public V put(K key, V value) { - if (isInRange(key)) { - return backingMap.put(key, value); + @Override + public V put(K key, V value) { + if (isInRange(key)) { + return backingMap.put(key, value); + } + throw new IllegalArgumentException(); } - throw new IllegalArgumentException(); - } - @SuppressWarnings("unchecked") - @Override - public V remove(Object key) { - if (isInRange((K) key)) { - return backingMap.remove(key); + @SuppressWarnings("unchecked") + @Override + public V remove(Object key) { + if (isInRange((K)key)) { + return backingMap.remove(key); + } + return null; } - return null; - } - public SortedMap subMap(K startKey, K endKey) { - checkRange(startKey); - checkRange(endKey); - Comparator c = backingMap.comparator(); - if (c == null) { - if (toComparable(startKey).compareTo(endKey) <= 0) { - return new SubMap(startKey, backingMap, endKey); + public SortedMap subMap(K startKey, K endKey) { + checkRange(startKey); + checkRange(endKey); + Comparator 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); + } } - } else { - if (c.compare(startKey, endKey) <= 0) { - return new SubMap(startKey, backingMap, endKey); + throw new IllegalArgumentException(); + } + + public SortedMap tailMap(K startKey) { + checkRange(startKey); + if (hasEnd) { + return new SubMap(startKey, backingMap, endKey); } + return new SubMap(startKey, backingMap); } - throw new IllegalArgumentException(); - } - public SortedMap tailMap(K startKey) { - checkRange(startKey); - if (hasEnd) { - return new SubMap(startKey, backingMap, endKey); + @Override + public Collection values() { + if(valuesCollection==null) { + valuesCollection = new SubMapValuesCollection(this); + } + return valuesCollection; } - return new SubMap(startKey, backingMap); - } - @Override - public Collection values() { - if (valuesCollection == null) { - valuesCollection = new SubMapValuesCollection(this); + public int size() { + if(backingMap.isSmall()) { + int start,end; + if (!hasStart) { + start = backingMap.small_left; + } else { + start = backingMap.smallFindAfter(startKey); + } + System.out.println(start); + if (!hasEnd) { + end = backingMap.small_right; + } else { + end = backingMap.smallFindBefore(endKey); + } + System.out.println(end); + if(backingMap.small_left<=start && end <=backingMap.small_right && end-start>=0) { + return end-start+1; + } else { + return 0; + } + } + TreeMap.Entry entry = firstEntry(); + if(entry!=null) { + int cnt=1; + if(hasEnd) { + TreeMap.Entry last = lastEntry(); + while(entry!=last){ + entry = successor(entry); + cnt++; + } + } else { + while((entry=successor(entry))!=null) cnt++; + } + return cnt; + } + return 0; } - return valuesCollection; + } - } - static class SubMapEntrySet extends AbstractSet> - implements Set> { - SubMap subMap; + static class SubMapEntrySet extends AbstractSet> implements Set> { + SubMap subMap; - SubMapEntrySet(SubMap map) { - subMap = map; - } + SubMapEntrySet(SubMap map) { + subMap = map; + } - @Override - public boolean isEmpty() { - return subMap.isEmpty(); - } + @Override + public boolean isEmpty() { + return subMap.isEmpty(); + } - @Override - public Iterator> iterator() { - TreeMap.Entry startNode = subMap.firstEntry(); - if (subMap.hasEnd) { - Comparator cmp = subMap.comparator(); - if (cmp == null) { - return new ComparableBoundedEntryIterator( - subMap.backingMap, startNode, - toComparable(subMap.endKey)); + @Override + public Iterator> iterator() { + if(subMap.backingMap.isSmall()) { + int start, end; + if(subMap.hasStart) { + start = subMap.backingMap.smallFindAfter(subMap.startKey); + } else { + start = subMap.backingMap.small_left; + } + if(subMap.hasEnd) { + end = subMap.backingMap.smallFindBefore(subMap.endKey); + } else { + end = subMap.backingMap.small_right; + } + return new SmallEntryIterator(subMap.backingMap,start,end); } - return new ComparatorBoundedEntryIterator( - subMap.backingMap, startNode, subMap.endKey); + TreeMap.Entry startNode = subMap.firstEntry(); + if (subMap.hasEnd) { + TreeMap.Entry lastNode = subMap.lastEntry(); + return new BoundedEntryIterator(subMap.backingMap, startNode, lastNode); + } + return new UnboundedEntryIterator(subMap.backingMap, startNode); } - return new UnboundedEntryIterator(subMap.backingMap, - startNode); - } - @Override - public int size() { - int size = 0; - Iterator> it = iterator(); - while (it.hasNext()) { - size++; - it.next(); + @Override + public int size() { + return subMap.size(); } - return size; - } - @SuppressWarnings("unchecked") - @Override - public boolean contains(Object object) { - if (object instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) object; - K key = entry.getKey(); - if (subMap.isInRange(key)) { - V v1 = subMap.get(key), v2 = entry.getValue(); - return v1 == null ? v2 == null : v1.equals(v2); + @SuppressWarnings("unchecked") + @Override + public boolean contains(Object object) { + if (object instanceof Map.Entry) { + Map.Entry entry = (Map.Entry) object; + K key = entry.getKey(); + if (subMap.isInRange(key)) { + V v1 = subMap.get(key), v2 = entry.getValue(); + return v1 == null ? v2 == null : v1.equals(v2); + } } + return false; } - return false; + } - } + static class SubMapKeySet extends AbstractSet implements Set { + SubMap subMap; - static class SubMapKeySet extends AbstractSet implements Set { - SubMap subMap; + SubMapKeySet(SubMap map) { + subMap = map; + } - SubMapKeySet(SubMap map) { - subMap = map; - } + @Override + public boolean contains(Object object) { + return subMap.containsKey(object); + } - @Override - public boolean contains(Object object) { - return subMap.containsKey(object); - } + @Override + public boolean isEmpty() { + return subMap.isEmpty(); + } - @Override - public boolean isEmpty() { - return subMap.isEmpty(); - } - - @Override - public int size() { - int size = 0; - Iterator it = iterator(); - while (it.hasNext()) { - size++; - it.next(); + @Override + public int size() { + return subMap.size(); } - return size; - } - @Override - public Iterator iterator() { - TreeMap.Entry startNode = subMap.firstEntry(); - if (subMap.hasEnd) { - Comparator cmp = subMap.comparator(); - if (cmp == null) { - return new ComparableBoundedKeyIterator( - subMap.backingMap, startNode, - toComparable(subMap.endKey)); + @Override + public Iterator iterator() { + if(subMap.backingMap.isSmall()) { + int start, end; + if(subMap.hasStart) { + start = subMap.backingMap.smallFindAfter(subMap.startKey); + } else { + start = subMap.backingMap.small_left; + } + if(subMap.hasEnd) { + end = subMap.backingMap.smallFindBefore(subMap.endKey); + } else { + end = subMap.backingMap.small_right; + } + return new SmallKeyIterator(subMap.backingMap,start,end); } - return new ComparatorBoundedKeyIterator( - subMap.backingMap, startNode, subMap.endKey); + TreeMap.Entry startNode = subMap.firstEntry(); + if (subMap.hasEnd) { + TreeMap.Entry lastNode = subMap.lastEntry(); + return new BoundedKeyIterator(subMap.backingMap, startNode, lastNode); + } + return new UnboundedKeyIterator(subMap.backingMap, startNode); } - return new UnboundedKeyIterator(subMap.backingMap, startNode); } - } - static class SubMapValuesCollection extends AbstractCollection { - SubMap subMap; + static class SubMapValuesCollection extends AbstractCollection { + SubMap subMap; - public SubMapValuesCollection(SubMap subMap) { - this.subMap = subMap; - } + public SubMapValuesCollection(SubMap subMap) { + this.subMap = subMap; + } - @Override - public boolean isEmpty() { - return subMap.isEmpty(); - } + @Override + public boolean isEmpty() { + return subMap.isEmpty(); + } - @Override - public Iterator iterator() { - TreeMap.Entry startNode = subMap.firstEntry(); - if (subMap.hasEnd) { - Comparator cmp = subMap.comparator(); - if (cmp == null) { - return new ComparableBoundedValueIterator( - subMap.backingMap, startNode, - toComparable(subMap.endKey)); + @Override + public Iterator iterator() { + if(subMap.backingMap.isSmall()) { + int start, end; + if(subMap.hasStart) { + start = subMap.backingMap.smallFindAfter(subMap.startKey); + } else { + start = subMap.backingMap.small_left; + } + if(subMap.hasEnd) { + end = subMap.backingMap.smallFindBefore(subMap.endKey); + } else { + end = subMap.backingMap.small_right; + } + return new SmallValueIterator(subMap.backingMap,start,end); } - return new ComparatorBoundedValueIterator( - subMap.backingMap, startNode, subMap.endKey); + TreeMap.Entry startNode = subMap.firstEntry(); + if (subMap.hasEnd) { + TreeMap.Entry lastNode = subMap.lastEntry(); + return new BoundedValueIterator(subMap.backingMap, startNode, lastNode); + } + return new UnboundedValueIterator(subMap.backingMap, startNode); } - return new UnboundedValueIterator(subMap.backingMap, - startNode); - } - @Override - public int size() { - int cnt = 0; - for (Iterator it = iterator(); it.hasNext();) { - it.next(); - cnt++; + @Override + public int size() { + return subMap.size(); } - return cnt; } - } - /** - * Constructs a new empty instance of TreeMap. - * - */ - public TreeMap() { - super(); + private void createSmall(){ + small_keys = (K[])new Object[SMALL_LIMIT]; + small_values = (V[])new Object[SMALL_LIMIT]; } - /** - * Constructs a new empty instance of TreeMap which uses the specified - * Comparator. - * - * @param comparator - * the Comparator - */ - public TreeMap(Comparator comparator) { - this.comparator = comparator; + private void clearSmall(){ + small_keys = null; + small_values = null; + small_entries = null; + small_right = -1; + small_left = 0; } - /** - * Constructs a new instance of TreeMap containing the mappings from the - * specified Map and using the natural ordering. - * - * @param map - * the mappings to add - * - * @exception ClassCastException - * when a key in the Map does not implement the Comparable - * interface, or they keys in the Map cannot be compared - */ - public TreeMap(Map map) { - this(); - putAll(map); + private boolean isSmall(){ + return small_keys!=null; } - /** - * Constructs a new instance of TreeMap containing the mappings from the - * specified SortedMap and using the same Comparator. - * - * @param map - * the mappings to add - */ - public TreeMap(SortedMap map) { - this(map.comparator()); - Iterator> it = map.entrySet() - .iterator(); - if (it.hasNext()) { - Map.Entry entry = it.next(); - Entry last = new Entry(entry.getKey(), entry.getValue()); - root = last; - size = 1; - while (it.hasNext()) { - entry = it.next(); - Entry x = new Entry(entry.getKey(), entry - .getValue()); - x.parent = last; - last.right = x; - size++; - balance(x); - last = x; - } - } - } + /** + * Constructs a new empty instance of TreeMap. + * + */ + public TreeMap() { + createSmall(); + } - void balance(Entry x) { - Entry 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); - } - } - } - root.color = false; - } + /** + * Constructs a new empty instance of TreeMap which uses the specified + * Comparator. + * + * @param comparator + * the Comparator + */ + public TreeMap(Comparator comparator) { + this.comparator = comparator; + createSmall(); + } - /** - * Removes all mappings from this TreeMap, leaving it empty. - * - * @see Map#isEmpty - * @see #size - */ - @Override + /** + * Constructs a new instance of TreeMap containing the mappings from the + * specified Map and using the natural ordering. + * + * @param map + * the mappings to add + * + * @exception ClassCastException + * when a key in the Map does not implement the Comparable + * interface, or they keys in the Map cannot be compared + */ + public TreeMap(Map map) { + putAll(map); + } + + /** + * Constructs a new instance of TreeMap containing the mappings from the + * specified SortedMap and using the same Comparator. + * + * @param map + * the mappings to add + */ + public TreeMap(SortedMap map) { + this.comparator = map.comparator(); + Iterator> it = map.entrySet().iterator(); + if (it.hasNext()) { + Map.Entry entry = it.next(); + Entry last = new Entry(entry.getKey(), entry.getValue()); + root = last; + size = 1; + while (it.hasNext()) { + entry = it.next(); + Entry x = new Entry(entry.getKey(), entry.getValue()); + x.parent = last; + last.right = x; + size++; + balance(x); + last = x; + } + } + } + + void balance(Entry x) { + Entry 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); + } + } + } + root.color = false; + } + + /** + * Removes all mappings from this TreeMap, leaving it empty. + * + * @see Map#isEmpty + * @see #size + */ + @Override public void clear() { - root = null; - size = 0; - modCount++; - } + root = null; + size = 0; + modCount++; + clearSmall(); + createSmall(); + } - /** - * Answers a new TreeMap with the same mappings, size and comparator as this - * TreeMap. - * - * @return a shallow copy of this TreeMap - * - * @see java.lang.Cloneable - */ - @SuppressWarnings("unchecked") + /** + * Answers a new TreeMap with the same mappings, size and comparator as this + * TreeMap. + * + * @return a shallow copy of this TreeMap + * + * @see java.lang.Cloneable + */ + @SuppressWarnings("unchecked") @Override public Object clone() { - try { - TreeMap clone = (TreeMap) super.clone(); - clone.entrySet = null; - if (root != null) { + try { + TreeMap clone = (TreeMap) super.clone(); + clone.entrySet = null; + if (root != null) { clone.root = root.clone(null); + } else if(isSmall()) { + clone.createSmall(); + clone.small_entries = null; + System.arraycopy(small_keys,0,clone.small_keys,0,small_keys.length); + System.arraycopy(small_values,0,clone.small_values,0,small_values.length); + clone.small_left = small_left; + clone.small_right = small_right; } - return clone; - } catch (CloneNotSupportedException e) { - return null; - } - } + return clone; + } catch (CloneNotSupportedException e) { + return null; + } + } - /** - * Answers the Comparator used to compare elements in this TreeMap. - * - * @return a Comparator or null if the natural ordering is used - */ - public Comparator comparator() { - return comparator; - } + /** + * Answers the Comparator used to compare elements in this TreeMap. + * + * @return a Comparator or null if the natural ordering is used + */ + public Comparator comparator() { + return comparator; + } - /** - * Searches this TreeMap for the specified key. - * - * @param key - * the object to search for - * @return true if key is a key of this TreeMap, false - * otherwise - * - * @exception ClassCastException - * when the key cannot be compared with the keys in this - * TreeMap - * @exception NullPointerException - * when the key is null and the comparator cannot handle null - */ + /** + * Searches this TreeMap for the specified key. + * + * @param key + * the object to search for + * @return true if key is a key of this TreeMap, false + * otherwise + * + * @exception ClassCastException + * when the key cannot be compared with the keys in this + * TreeMap + * @exception NullPointerException + * when the key is null and the comparator cannot handle null + */ @Override public boolean containsKey(Object key) { - return find(key) != null; - } + return isSmall() ? smallFind(key)>=0 : find(key) != null; + } - /** - * Searches this TreeMap for the specified value. - * - * @param value - * the object to search for - * @return true if value is a value of this TreeMap, false - * otherwise - */ + /** + * Searches this TreeMap for the specified value. + * + * @param value + * the object to search for + * @return true if value is a value of this TreeMap, false + * otherwise + */ @Override public boolean containsValue(Object value) { if (root != null) { return containsValue(root, value); + } else if (size > 0 & isSmall()) { + if (value == null) { + for (int i = small_left; i <= small_right; i++) { + if (small_values[i] == null) { + return true; + } + } + } else { + for (int i = small_left; i <= small_right; i++) { + if (value.equals(small_values[i])) { + return true; + } + } + } } return false; } - private boolean containsValue(Entry node, Object value) { - if (value == null ? node.value == null : value.equals(node.value)) { + private boolean containsValue(Entry node, Object value) { + if (value == null ? node.value == null : value.equals(node.value)) { return true; } - if (node.left != null) { + if (node.left != null) { if (containsValue(node.left, value)) { return true; } } - if (node.right != null) { + if (node.right != null) { if (containsValue(node.right, value)) { return true; } } - return false; - } + return false; + } - /** - * Answers a Set of the mappings contained in this TreeMap. Each element in - * the set is a Map.Entry. The set is backed by this TreeMap so changes to - * one are reflected by the other. The set does not support adding. - * - * @return a Set of the mappings - */ - @Override + /** + * Answers a Set of the mappings contained in this TreeMap. Each element in + * the set is a Map.Entry. The set is backed by this TreeMap so changes to + * one are reflected by the other. The set does not support adding. + * + * @return a Set of the mappings + */ + @Override public Set> entrySet() { if (entrySet == null) { entrySet = new AbstractSet>() { - @Override + @Override public int size() { return size; } @@ -923,6 +1090,9 @@ @Override public Iterator> iterator() { + if(isSmall()) { + return new SmallEntryIterator(TreeMap.this,TreeMap.this.small_left,TreeMap.this.small_right); + } return new UnboundedEntryIterator(TreeMap.this); } }; @@ -930,386 +1100,541 @@ return entrySet; } - @SuppressWarnings("unchecked") - private Entry find(Object keyObj) { - int result; + /** @return the non-negative index of the element, or a negative index which + * is the -index - 1 where the element would be inserted + */ + private int smallFind(Object keyObj) { + if (small_left > small_right) { + return -1; + } K key = (K) keyObj; - Comparable object = null; if (comparator == null) { + Comparable object = toComparable(key); + int low = small_left, mid = 0, high = small_right, result = 0; + while (low <= high) { + mid = (low + high) >> 1; + if ((result = object.compareTo(small_keys[mid])) > 0) { + low = mid + 1; + } else if (result == 0) { + return mid; + } else { + high = mid - 1; + } + } + return -mid - (result <= 0 ? 1 : 2); + } else { + int low = small_left, mid = 0, high = small_right, result = 0; + while (low <= high) { + mid = (low + high) >> 1; + if ((result = comparator.compare(key, small_keys[mid])) > 0) { + low = mid + 1; + } else if (result == 0) { + return mid; + } else { + high = mid - 1; + } + } + return -mid - (result <= 0 ? 1 : 2); + } + } + + @SuppressWarnings("unchecked") + private Entry find(Object keyObj) { + int result; + K key = (K)keyObj; + Comparable object = null; + if (comparator == null) { object = toComparable(key); - Entry x = root; - while (x != null) { - result = object.compareTo(x.key); - if (result == 0) { + Entry x = root; + while (x != null) { + result = object.compareTo(x.key); + if (result == 0) { return x; } - x = result < 0 ? x.left : x.right; - } + x = result < 0 ? x.left : x.right; + } } else { - Entry x = root; - while (x != null) { - result = comparator.compare(key, x.key); - if (result == 0) { + Entry x = root; + while (x != null) { + result = comparator.compare(key, x.key); + if (result == 0) { return x; } - x = result < 0 ? x.left : x.right; - } + x = result < 0 ? x.left : x.right; + } } - return null; + return null; + } + + int smallFindAfter(Object keyObj) { + int idx = smallFind(keyObj); + if(idx>=0) { + return idx; + } else { + idx = -idx - 1; + return (idx>small_right) ? -1 : idx; + } } - @SuppressWarnings("unchecked") + int smallFindBefore(Object keyObj) { + int idx = smallFind(keyObj); + if(idx>=0) { + return (idx==small_left) ? -1 : idx-1; + } else { + idx = -idx - 1; + return (idx<=small_left) ? -1 : idx-1; + } + } + + @SuppressWarnings("unchecked") Entry findAfter(Object keyObj) { - K key = (K) keyObj; - int result; - Comparable object = null; - if (comparator == null) { + K key = (K)keyObj; + int result; + Comparable object = null; + if (comparator == null) { object = toComparable(key); } - Entry x = root, last = null; - while (x != null) { - result = object != null ? object.compareTo(x.key) : comparator - .compare(key, x.key); - if (result == 0) { + Entry x = root, last = null; + while (x != null) { + result = object != null ? object.compareTo(x.key) : comparator + .compare(key, x.key); + if (result == 0) { return x; } - if (result < 0) { - last = x; - x = x.left; - } else { + if (result < 0) { + last = x; + x = x.left; + } else { x = x.right; } - } - return last; - } + } + return last; + } - Entry findBefore(K key) { - int result; + Entry findBefore(K key) { + int result; Comparable object = null; - if (comparator == null) { + if (comparator == null) { object = toComparable(key); } - Entry x = root, last = null; - while (x != null) { - result = object != null ? object.compareTo(x.key) : comparator - .compare(key, x.key); - if (result <= 0) { + Entry x = root, last = null; + while (x != null) { + result = object != null ? object.compareTo(x.key) : comparator + .compare(key, x.key); + if (result <= 0) { x = x.left; } else { - last = x; - x = x.right; - } - } - return last; - } + last = x; + x = x.right; + } + } + return last; + } - /** - * Answer the first sorted key in this TreeMap. - * - * @return the first sorted key - * - * @exception NoSuchElementException - * when this TreeMap is empty - */ - public K firstKey() { - if (root != null) { + /** + * Answer the first sorted key in this TreeMap. + * + * @return the first sorted key + * + * @exception NoSuchElementException + * when this TreeMap is empty + */ + public K firstKey() { + if (root != null) { return minimum(root).key; + } else if(size>0 & isSmall()) { + return small_keys[small_left]; } - throw new NoSuchElementException(); - } + throw new NoSuchElementException(); + } - private void fixup(Entry x) { - Entry 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; - } + private void fixup(Entry x) { + Entry 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; + } - /** - * Answers the value of the mapping with the specified key. - * - * @param key - * the key - * @return the value of the mapping with the specified key - * - * @exception ClassCastException - * when the key cannot be compared with the keys in this - * TreeMap - * @exception NullPointerException - * when the key is null and the comparator cannot handle null - */ - @Override + /** + * Answers the value of the mapping with the specified key. + * + * @param key + * the key + * @return the value of the mapping with the specified key + * + * @exception ClassCastException + * when the key cannot be compared with the keys in this + * TreeMap + * @exception NullPointerException + * when the key is null and the comparator cannot handle null + */ + @Override public V get(Object key) { - Entry node = find(key); - if (node != null) { - return node.value; + if(isSmall()) { + int idx = smallFind(key); + if(idx >= 0) { + return small_values[idx]; + } + } else { + Entry node = find(key); + if (node != null) { + return node.value; + } } - return null; - } + return null; + } - /** - * Answers a SortedMap of the specified portion of this TreeMap which - * contains keys less than the end key. The returned SortedMap is backed by - * this TreeMap so changes to one are reflected by the other. - * - * @param endKey - * the end key - * @return a sub-map where the keys are less than endKey - * - * @exception ClassCastException - * when the end key cannot be compared with the keys in this - * TreeMap - * @exception NullPointerException - * when the end key is null and the comparator cannot handle - * null - */ - public SortedMap headMap(K endKey) { - // Check for errors - if (comparator == null) { + /** + * Answers a SortedMap of the specified portion of this TreeMap which + * contains keys less than the end key. The returned SortedMap is backed by + * this TreeMap so changes to one are reflected by the other. + * + * @param endKey + * the end key + * @return a sub-map where the keys are less than endKey + * + * @exception ClassCastException + * when the end key cannot be compared with the keys in this + * TreeMap + * @exception NullPointerException + * when the end key is null and the comparator cannot handle + * null + */ + public SortedMap headMap(K endKey) { + // Check for errors + if (comparator == null) { toComparable(endKey).compareTo(endKey); } else { comparator.compare(endKey, endKey); } - return new SubMap(this, endKey); - } + return new SubMap(this, endKey); + } - /** - * Answers a Set of the keys contained in this TreeMap. The set is backed by - * this TreeMap so changes to one are reflected by the other. The set does - * not support adding. - * - * @return a Set of the keys - */ - @Override + /** + * Answers a Set of the keys contained in this TreeMap. The set is backed by + * this TreeMap so changes to one are reflected by the other. The set does + * not support adding. + * + * @return a Set of the keys + */ + @Override public Set keySet() { - if (keySet == null) { - keySet = new AbstractSet() { - @Override + if (keySet == null) { + keySet = new AbstractSet() { + @Override public boolean contains(Object object) { - return containsKey(object); - } + return containsKey(object); + } - @Override + @Override public int size() { - return size; - } + return size; + } - @Override + @Override public void clear() { - TreeMap.this.clear(); - } + TreeMap.this.clear(); + } - @Override + @Override public Iterator iterator() { - return new UnboundedKeyIterator(TreeMap.this); - } - }; - } - return keySet; - } + if(isSmall()) { + return new SmallKeyIterator(TreeMap.this,TreeMap.this.small_left,TreeMap.this.small_right); + } + return new UnboundedKeyIterator (TreeMap.this); + } + }; + } + return keySet; + } - /** - * Answer the last sorted key in this TreeMap. - * - * @return the last sorted key - * - * @exception NoSuchElementException - * when this TreeMap is empty - */ - public K lastKey() { - if (root != null) { + /** + * Answer the last sorted key in this TreeMap. + * + * @return the last sorted key + * + * @exception NoSuchElementException + * when this TreeMap is empty + */ + public K lastKey() { + if (root != null) { return maximum(root).key; + } else if(size>0 && isSmall()) { + return small_keys[small_right]; } - throw new NoSuchElementException(); - } + throw new NoSuchElementException(); + } - private void leftRotate(Entry x) { - Entry y = x.right; - x.right = y.left; - if (y.left != null) { + private void leftRotate(Entry x) { + Entry 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) { + 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; - } + } + y.left = x; + x.parent = y; + } - static Entry maximum(Entry x) { - while (x.right != null) { + static Entry maximum(Entry x) { + while (x.right != null) { x = x.right; } - return x; - } + return x; + } - static Entry minimum(Entry x) { - while (x.left != null) { + static Entry minimum(Entry x) { + while (x.left != null) { x = x.left; } - return x; - } + return x; + } - static Entry predecessor(Entry x) { - if (x.left != null) { + static Entry predecessor(Entry x) { + if (x.left != null) { return maximum(x.left); } - Entry y = x.parent; - while (y != null && x == y.left) { - x = y; - y = y.parent; + Entry y = x.parent; + while (y != null && x == y.left) { + x = y; + y = y.parent; + } + return y; + } + + private Entry smallDeflate(int from, int to){ + int elem = (from+to)>>1; + Entry entry = small_entries==null? null:small_entries[elem]; + if(entry == null) { + entry= new Entry(small_keys[elem],small_values[elem]); } - return y; + if(from<=elem-1) { + entry.left = smallDeflate(from,elem-1); + entry.left.parent = entry; + } + if(elem+1<=to) { + entry.right = smallDeflate(elem+1,to); + entry.right.parent = entry; + } + return entry; } - /** - * Maps the specified key to the specified value. - * - * @param key - * the key - * @param value - * the value - * @return the value of any previous mapping with the specified key or null - * if there was no mapping - * - * @exception ClassCastException - * when the key cannot be compared with the keys in this - * TreeMap - * @exception NullPointerException - * when the key is null and the comparator cannot handle null - */ - @Override + /** + * Maps the specified key to the specified value. + * + * @param key + * the key + * @param value + * the value + * @return the value of any previous mapping with the specified key or null + * if there was no mapping + * + * @exception ClassCastException + * when the key cannot be compared with the keys in this + * TreeMap + * @exception NullPointerException + * when the key is null and the comparator cannot handle null + */ + @Override public V put(K key, V value) { - MapEntry entry = rbInsert(key); - V result = entry.value; - entry.value = value; - return result; - } + if(isSmall()) { + if(small_left>small_right) { + small_left = small_right = 0; + small_keys[0] = key; + small_values[0] = value; + modCount++; + size++; + return null; + } else { + int idx = smallFind(key); + if(idx>=0) { + V res = small_values[idx]; + small_values[idx] = value; + if(small_entries!=null && small_entries[idx]!=null) { + small_entries[idx].value = value; + } + return res; + } + if(size == SMALL_LIMIT) { + root = smallDeflate(small_left,small_right); + clearSmall(); + } else { + int newIdx = -idx - 1; + if((small_left==0)||((small_right - newIdx) <= (newIdx - small_left) && ((small_right < SMALL_LIMIT-1)))) { + // move right + System.arraycopy(small_keys,newIdx,small_keys,newIdx+1,small_right-newIdx+1); + System.arraycopy(small_values,newIdx,small_values,newIdx+1,small_right-newIdx+1); + if(small_entries!=null) { + System.arraycopy(small_entries,newIdx,small_entries,newIdx+1,small_right-newIdx+1); + } +// for(int i=small_right; i >= newIdx; i--){ +// small_keys[i+1] = small_keys[i]; +// small_values[i+1] = small_values[i]; +// if(small_entries!=null) { +// small_entries[i+1] = small_entries[i]; +// } +// } + small_right++; + } else { + System.arraycopy(small_keys,small_left,small_keys,small_left-1,newIdx-small_left); + System.arraycopy(small_values,small_left,small_values,small_left-1,newIdx-small_left); + if(small_entries!=null) { + System.arraycopy(small_entries,small_left,small_entries,small_left-1,newIdx-small_left); + } +// for (int i = small_left; i < newIdx; i++) { +// small_keys[i - 1] = small_keys[i]; +// small_values[i - 1] = small_values[i]; +// if (small_entries != null) { +// small_entries[i - 1] = small_entries[i]; +// } +// } + small_left--; + newIdx--; + } + small_keys[newIdx] = key; + small_values[newIdx] = value; + if(small_entries!=null) { + small_keys[newIdx] = null; + } + size++; + modCount++; + return null; + } + } + } + MapEntry entry = rbInsert(key); + V result = entry.value; + entry.value = value; + return result; + } + /** - * Copies every mapping in the specified Map to this TreeMap. - * - * @param map - * the Map to copy mappings from - * - * @exception ClassCastException - * when a key in the Map cannot be compared with the keys in - * this TreeMap - * @exception NullPointerException - * when a key in the Map is null and the comparator cannot - * handle null - */ - @Override + * Copies every mapping in the specified Map to this TreeMap. + * + * @param map + * the Map to copy mappings from + * + * @exception ClassCastException + * when a key in the Map cannot be compared with the keys in + * this TreeMap + * @exception NullPointerException + * when a key in the Map is null and the comparator cannot + * handle null + */ + @Override public void putAll(Map map) { - super.putAll(map); - } + super.putAll(map); + } - void rbDelete(Entry z) { - Entry y = z.left == null || z.right == null ? z : successor(z); - Entry x = y.left != null ? y.left : y.right; - if (x != null) { + void rbDelete(Entry z) { + Entry y = z.left == null || z.right == null ? z : successor(z); + Entry x = y.left != null ? y.left : y.right; + if (x != null) { x.parent = y.parent; } - if (y.parent == null) { + if (y.parent == null) { root = x; } else if (y == y.parent.left) { y.parent.left = x; } else { y.parent.right = x; } - modCount++; - if (y != z) { - z.key = y.key; - z.value = y.value; - } - if (!y.color && root != null) { - if (x == null) { + modCount++; + if (y != z) { + z.key = y.key; + z.value = y.value; + } + if (!y.color && root != null) { + if (x == null) { fixup(y.parent); } else { fixup(x); } - } + } y.left = y.right = y.parent = null; - size--; - } + size--; + } - private Entry rbInsert(K object) { - int result = 0; - Entry y = null; + private Entry rbInsert(K object) { + int result = 0; + Entry y = null; if (size != 0) { Comparable key = null; if (comparator == null) { @@ -1336,218 +1661,284 @@ } } - - size++; - modCount++; - Entry z = new Entry(object); - if (y == null) { + size++; + modCount++; + Entry z = new Entry(object); + if (y == null) { return root = z; } - z.parent = y; - if (result < 0) { + z.parent = y; + if (result < 0) { y.left = z; } else { y.right = z; } - balance(z); - return z; - } + balance(z); + return z; + } - /** - * Removes a mapping with the specified key from this TreeMap. - * - * @param key - * the key of the mapping to remove - * @return the value of the removed mapping or null if key is not a key in - * this TreeMap - * - * @exception ClassCastException - * when the key cannot be compared with the keys in this - * TreeMap - * @exception NullPointerException - * when the key is null and the comparator cannot handle null - */ - @Override + /** + * Removes a mapping with the specified key from this TreeMap. + * + * @param key + * the key of the mapping to remove + * @return the value of the removed mapping or null if key is not a key in + * this TreeMap + * + * @exception ClassCastException + * when the key cannot be compared with the keys in this + * TreeMap + * @exception NullPointerException + * when the key is null and the comparator cannot handle null + */ + @Override public V remove(Object key) { - if (size == 0) { - return null; + if (size == 0) { + return null; + } + if(isSmall()){ + int idx = smallFind(key); + if(idx<0) { + return null; + } + V result = small_values[idx]; + smallDelete(idx); + return result; + } else { + Entry node = find(key); + if (node == null) { + return null; + } + V result = node.value; + rbDelete(node); + return result; } - Entry node = find(key); - if (node == null) { - return null; + } + + private boolean smallDelete(int idx) { + size--; + modCount++; + if(idx==small_left) { + small_keys[idx] = null; + small_values[idx] = null; + if(small_entries!=null) { + small_keys[idx] = null; + } + small_left++; + return false; + } else if(idx==small_right) { + small_right--; + small_keys[idx] = null; + small_values[idx] = null; + if(small_entries!=null) { + small_keys[idx] = null; + } + } else { + + System.arraycopy(small_keys,idx+1,small_keys,idx,small_right-idx); + System.arraycopy(small_values,idx+1,small_values,idx,small_right-idx); + if(small_entries!=null) { + System.arraycopy(small_entries,idx+1,small_entries,idx,small_right-idx); + } +// for(int i=idx+1; i<=small_right; i++) { +// small_keys[i-1] = small_keys[i]; +// small_values[i-1] = small_values[i]; +// if(small_entries!=null) { +// small_entries[i-1] = small_entries[i]; +// } +// } + small_right--; } - V result = node.value; - rbDelete(node); - return result; + return true; } private void rightRotate(Entry x) { - Entry y = x.left; - x.left = y.right; - if (y.right != null) { + Entry y = x.left; + x.left = y.right; + if (y.right != null) { y.right.parent = x; } - y.parent = x.parent; - if (x.parent == null) { - root = y; - } else { - if (x == x.parent.right) { + 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; - } + } + y.right = x; + x.parent = y; + } - /** - * Answers the number of mappings in this TreeMap. - * - * @return the number of mappings in this TreeMap - */ - @Override + /** + * Answers the number of mappings in this TreeMap. + * + * @return the number of mappings in this TreeMap + */ + @Override public int size() { - return size; - } + return size; + } - /** - * Answers a SortedMap of the specified portion of this TreeMap which - * contains keys greater or equal to the start key but less than the end - * key. The returned SortedMap is backed by this TreeMap so changes to one - * are reflected by the other. - * - * @param startKey - * the start key - * @param endKey - * the end key - * @return a sub-map where the keys are greater or equal to - * startKey and less than endKey - * - * @exception ClassCastException - * when the start or end key cannot be compared with the keys - * in this TreeMap - * @exception NullPointerException - * when the start or end key is null and the comparator - * cannot handle null - */ - public SortedMap subMap(K startKey, K endKey) { - if (comparator == null) { - if (toComparable(startKey).compareTo(endKey) <= 0) { + /** + * Answers a SortedMap of the specified portion of this TreeMap which + * contains keys greater or equal to the start key but less than the end + * key. The returned SortedMap is backed by this TreeMap so changes to one + * are reflected by the other. + * + * @param startKey + * the start key + * @param endKey + * the end key + * @return a sub-map where the keys are greater or equal to + * startKey and less than endKey + * + * @exception ClassCastException + * when the start or end key cannot be compared with the keys + * in this TreeMap + * @exception NullPointerException + * when the start or end key is null and the comparator + * cannot handle null + */ + public SortedMap subMap(K startKey, K endKey) { + if (comparator == null) { + if (toComparable(startKey).compareTo(endKey) <= 0) { return new SubMap(startKey, this, endKey); } - } else { - if (comparator.compare(startKey, endKey) <= 0) { + } else { + if (comparator.compare(startKey, endKey) <= 0) { return new SubMap(startKey, this, endKey); } - } - throw new IllegalArgumentException(); - } + } + throw new IllegalArgumentException(); + } - static Entry successor(Entry x) { - if (x.right != null) { + static Entry successor(Entry x) { + if (x.right != null) { return minimum(x.right); } - Entry y = x.parent; - while (y != null && x == y.right) { - x = y; - y = y.parent; - } - return y; - } + Entry y = x.parent; + while (y != null && x == y.right) { + x = y; + y = y.parent; + } + return y; + } - /** - * Answers a SortedMap of the specified portion of this TreeMap which - * contains keys greater or equal to the start key. The returned SortedMap - * is backed by this TreeMap so changes to one are reflected by the other. - * - * @param startKey - * the start key - * @return a sub-map where the keys are greater or equal to - * startKey - * - * @exception ClassCastException - * when the start key cannot be compared with the keys in - * this TreeMap - * @exception NullPointerException - * when the start key is null and the comparator cannot - * handle null - */ - public SortedMap tailMap(K startKey) { - // Check for errors - if (comparator == null) { + /** + * Answers a SortedMap of the specified portion of this TreeMap which + * contains keys greater or equal to the start key. The returned SortedMap + * is backed by this TreeMap so changes to one are reflected by the other. + * + * @param startKey + * the start key + * @return a sub-map where the keys are greater or equal to + * startKey + * + * @exception ClassCastException + * when the start key cannot be compared with the keys in + * this TreeMap + * @exception NullPointerException + * when the start key is null and the comparator cannot + * handle null + */ + public SortedMap tailMap(K startKey) { + // Check for errors + if (comparator == null) { toComparable(startKey).compareTo(startKey); } else { comparator.compare(startKey, startKey); } - return new SubMap(startKey, this); - } + return new SubMap(startKey, this); + } - /** - * Answers a Collection of the values contained in this TreeMap. The - * collection is backed by this TreeMap so changes to one are reflected by - * the other. The collection does not support adding. - * - * @return a Collection of the values - */ - @Override + /** + * Answers a Collection of the values contained in this TreeMap. The + * collection is backed by this TreeMap so changes to one are reflected by + * the other. The collection does not support adding. + * + * @return a Collection of the values + */ + @Override public Collection values() { - if (valuesCollection == null) { - valuesCollection = new AbstractCollection() { - @Override + if (valuesCollection == null) { + valuesCollection = new AbstractCollection() { + @Override public boolean contains(Object object) { - return containsValue(object); - } + return containsValue(object); + } - @Override + @Override public int size() { - return size; - } + return size; + } - @Override + @Override public void clear() { - TreeMap.this.clear(); - } + TreeMap.this.clear(); + } - @Override + @Override public Iterator iterator() { - return new UnboundedValueIterator(TreeMap.this); + if(isSmall()) { + return new SmallValueIterator(TreeMap.this,TreeMap.this.small_left,TreeMap.this.small_right); + } + return new UnboundedValueIterator (TreeMap.this); + } + }; + } + return valuesCollection; + } + + private void writeObject(ObjectOutputStream stream) throws IOException { + stream.defaultWriteObject(); + stream.writeInt(size); + if (size > 0) { + if(isSmall()) { + for(int i=small_left; i<=small_right; i++){ + stream.writeObject(small_keys[i]); + stream.writeObject(small_values[i]); } - }; - } - return valuesCollection; - } - - private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); - stream.writeInt(size); - if (size > 0) { - Entry node = minimum(root); - while (node != null) { - stream.writeObject(node.key); - stream.writeObject(node.value); - node = successor(node); + } else { + Entry node = minimum(root); + while (node != null) { + stream.writeObject(node.key); + stream.writeObject(node.value); + node = successor(node); + } } - } - } + } + } - @SuppressWarnings("unchecked") + @SuppressWarnings("unchecked") private void readObject(ObjectInputStream stream) throws IOException, - ClassNotFoundException { - stream.defaultReadObject(); - size = stream.readInt(); - Entry last = null; - for (int i = size; --i >= 0;) { - Entry node = new Entry((K) stream.readObject()); - node.value = (V) stream.readObject(); - if (last == null) { - root = node; - } else { - node.parent = last; - last.right = node; - balance(node); + ClassNotFoundException { + stream.defaultReadObject(); + size = stream.readInt(); + if(size>0 && size last = null; + for (int i = size; --i >= 0;) { + Entry node = new Entry((K)stream.readObject()); + node.value = (V)stream.readObject(); + if (last == null) { + root = node; + } else { + node.parent = last; + last.right = node; + balance(node); + } + last = node; + } } - } + } }