Use 'a' operand code for prefetch instruction.
[official-gcc.git] / libjava / java / util / TreeMap.java
blob83386d6e54b6b646acb7169cef0a676ac88715a9
1 /* TreeMap.java -- a class providing a basic Red-Black Tree data structure,
2 mapping Object --> Object
3 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA.
22 As a special exception, if you link this library with other files to
23 produce an executable, this library does not by itself cause the
24 resulting executable to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why the
26 executable file might be covered by the GNU General Public License. */
29 package java.util;
31 import java.io.Serializable;
32 import java.io.ObjectOutputStream;
33 import java.io.ObjectInputStream;
34 import java.io.IOException;
36 /**
37 * This class provides a red-black tree implementation of the SortedMap
38 * interface. Elements in the Map will be sorted by either a user-provided
39 * Comparator object, or by the natural ordering of the keys.
41 * The algorithms are adopted from Corman, Leiserson, and Rivest's
42 * <i>Introduction to Algorithms.</i> TreeMap guarantees O(log n)
43 * insertion and deletion of elements. That being said, there is a large
44 * enough constant coefficient in front of that "log n" (overhead involved
45 * in keeping the tree balanced), that TreeMap may not be the best choice
46 * for small collections. If something is already sorted, you may want to
47 * just use a LinkedHashMap to maintain the order while providing O(1) access.
49 * TreeMap is a part of the JDK1.2 Collections API. Null keys are allowed
50 * only if a Comparator is used which can deal with them; natural ordering
51 * cannot cope with null. Null values are always allowed. Note that the
52 * ordering must be <i>consistent with equals</i> to correctly implement
53 * the Map interface. If this condition is violated, the map is still
54 * well-behaved, but you may have suprising results when comparing it to
55 * other maps.<p>
57 * This implementation is not synchronized. If you need to share this between
58 * multiple threads, do something like:<br>
59 * <code>SortedMap m
60 * = Collections.synchronizedSortedMap(new TreeMap(...));</code><p>
62 * The iterators are <i>fail-fast</i>, meaning that any structural
63 * modification, except for <code>remove()</code> called on the iterator
64 * itself, cause the iterator to throw a
65 * <code>ConcurrentModificationException</code> rather than exhibit
66 * non-deterministic behavior.
68 * @author Jon Zeppieri
69 * @author Bryce McKinlay
70 * @author Eric Blake <ebb9@email.byu.edu>
71 * @see Map
72 * @see HashMap
73 * @see Hashtable
74 * @see LinkedHashMap
75 * @see Comparable
76 * @see Comparator
77 * @see Collection
78 * @see Collections#synchronizedSortedMap(SortedMap)
79 * @since 1.2
80 * @status updated to 1.4
82 public class TreeMap extends AbstractMap
83 implements SortedMap, Cloneable, Serializable
85 // Implementation note:
86 // A red-black tree is a binary search tree with the additional properties
87 // that all paths to a leaf node visit the same number of black nodes,
88 // and no red node has red children. To avoid some null-pointer checks,
89 // we use the special node nil which is always black, has no relatives,
90 // and has key and value of null (but is not equal to a mapping of null).
92 /**
93 * Compatible with JDK 1.2.
95 private static final long serialVersionUID = 919286545866124006L;
97 /**
98 * Color status of a node. Package visible for use by nested classes.
100 static final int RED = -1,
101 BLACK = 1;
104 * Sentinal node, used to avoid null checks for corner cases and make the
105 * delete rebalance code simpler. The rebalance code must never assign
106 * the parent, left, or right of nil, but may safely reassign the color
107 * to be black. This object must never be used as a key in a TreeMap, or
108 * it will break bounds checking of a SubMap.
110 static final Node nil = new Node(null, null, BLACK);
111 static
113 // Nil is self-referential, so we must initialize it after creation.
114 nil.parent = nil;
115 nil.left = nil;
116 nil.right = nil;
120 * The root node of this TreeMap.
122 private transient Node root = nil;
125 * The size of this TreeMap. Package visible for use by nested classes.
127 transient int size;
130 * The cache for {@link #entrySet()}.
132 private transient Set entries;
135 * Counts the number of modifications this TreeMap has undergone, used
136 * by Iterators to know when to throw ConcurrentModificationExceptions.
137 * Package visible for use by nested classes.
139 transient int modCount;
142 * This TreeMap's comparator, or null for natural ordering.
143 * Package visible for use by nested classes.
144 * @serial the comparator ordering this tree, or null
146 final Comparator comparator;
149 * Class to represent an entry in the tree. Holds a single key-value pair,
150 * plus pointers to parent and child nodes.
152 * @author Eric Blake <ebb9@email.byu.edu>
154 private static final class Node extends BasicMapEntry
156 // All fields package visible for use by nested classes.
157 /** The color of this node. */
158 int color;
160 /** The left child node. */
161 Node left = nil;
162 /** The right child node. */
163 Node right = nil;
164 /** The parent node. */
165 Node parent = nil;
168 * Simple constructor.
169 * @param key the key
170 * @param value the value
172 Node(Object key, Object value, int color)
174 super(key, value);
175 this.color = color;
180 * Instantiate a new TreeMap with no elements, using the keys' natural
181 * ordering to sort. All entries in the map must have a key which implements
182 * Comparable, and which are <i>mutually comparable</i>, otherwise map
183 * operations may throw a {@link ClassCastException}. Attempts to use
184 * a null key will throw a {@link NullPointerException}.
186 * @see Comparable
188 public TreeMap()
190 this((Comparator) null);
194 * Instantiate a new TreeMap with no elements, using the provided comparator
195 * to sort. All entries in the map must have keys which are mutually
196 * comparable by the Comparator, otherwise map operations may throw a
197 * {@link ClassCastException}.
199 * @param comparator the sort order for the keys of this map, or null
200 * for the natural order
202 public TreeMap(Comparator c)
204 comparator = c;
208 * Instantiate a new TreeMap, initializing it with all of the elements in
209 * the provided Map. The elements will be sorted using the natural
210 * ordering of the keys. This algorithm runs in n*log(n) time. All entries
211 * in the map must have keys which implement Comparable and are mutually
212 * comparable, otherwise map operations may throw a
213 * {@link ClassCastException}.
215 * @param map a Map, whose entries will be put into this TreeMap
216 * @throws ClassCastException if the keys in the provided Map are not
217 * comparable
218 * @throws NullPointerException if map is null
219 * @see Comparable
221 public TreeMap(Map map)
223 this((Comparator) null);
224 putAll(map);
228 * Instantiate a new TreeMap, initializing it with all of the elements in
229 * the provided SortedMap. The elements will be sorted using the same
230 * comparator as in the provided SortedMap. This runs in linear time.
232 * @param sm a SortedMap, whose entries will be put into this TreeMap
233 * @throws NullPointerException if sm is null
235 public TreeMap(SortedMap sm)
237 this(sm.comparator());
238 int pos = sm.size();
239 Iterator itr = sm.entrySet().iterator();
241 fabricateTree(pos);
242 Node node = firstNode();
244 while (--pos >= 0)
246 Map.Entry me = (Map.Entry) itr.next();
247 node.key = me.getKey();
248 node.value = me.getValue();
249 node = successor(node);
254 * Clears the Map so it has no keys. This is O(1).
256 public void clear()
258 if (size > 0)
260 modCount++;
261 root = nil;
262 size = 0;
267 * Returns a shallow clone of this TreeMap. The Map itself is cloned,
268 * but its contents are not.
270 * @return the clone
272 public Object clone()
274 TreeMap copy = null;
277 copy = (TreeMap) super.clone();
279 catch (CloneNotSupportedException x)
282 copy.entries = null;
283 copy.fabricateTree(size);
285 Node node = firstNode();
286 Node cnode = copy.firstNode();
288 while (node != nil)
290 cnode.key = node.key;
291 cnode.value = node.value;
292 node = successor(node);
293 cnode = copy.successor(cnode);
295 return copy;
299 * Return the comparator used to sort this map, or null if it is by
300 * natural order.
302 * @return the map's comparator
304 public Comparator comparator()
306 return comparator;
310 * Returns true if the map contains a mapping for the given key.
312 * @param key the key to look for
313 * @return true if the key has a mapping
314 * @throws ClassCastException if key is not comparable to map elements
315 * @throws NullPointerException if key is null and the comparator is not
316 * tolerant of nulls
318 public boolean containsKey(Object key)
320 return getNode(key) != nil;
324 * Returns true if the map contains at least one mapping to the given value.
325 * This requires linear time.
327 * @param value the value to look for
328 * @return true if the value appears in a mapping
330 public boolean containsValue(Object value)
332 Node node = firstNode();
333 while (node != nil)
335 if (equals(value, node.value))
336 return true;
337 node = successor(node);
339 return false;
343 * Returns a "set view" of this TreeMap's entries. The set is backed by
344 * the TreeMap, so changes in one show up in the other. The set supports
345 * element removal, but not element addition.<p>
347 * Note that the iterators for all three views, from keySet(), entrySet(),
348 * and values(), traverse the TreeMap in sorted sequence.
350 * @return a set view of the entries
351 * @see #keySet()
352 * @see #values()
353 * @see Map.Entry
355 public Set entrySet()
357 if (entries == null)
358 // Create an AbstractSet with custom implementations of those methods
359 // that can be overriden easily and efficiently.
360 entries = new AbstractSet()
362 public int size()
364 return size;
367 public Iterator iterator()
369 return new TreeIterator(ENTRIES);
372 public void clear()
374 TreeMap.this.clear();
377 public boolean contains(Object o)
379 if (! (o instanceof Map.Entry))
380 return false;
381 Map.Entry me = (Map.Entry) o;
382 Node n = getNode(me.getKey());
383 return n != nil && AbstractSet.equals(me.getValue(), n.value);
386 public boolean remove(Object o)
388 if (! (o instanceof Map.Entry))
389 return false;
390 Map.Entry me = (Map.Entry) o;
391 Node n = getNode(me.getKey());
392 if (n != nil && AbstractSet.equals(me.getValue(), n.value))
394 removeNode(n);
395 return true;
397 return false;
400 return entries;
404 * Returns the first (lowest) key in the map.
406 * @return the first key
407 * @throws NoSuchElementException if the map is empty
409 public Object firstKey()
411 if (root == nil)
412 throw new NoSuchElementException();
413 return firstNode().key;
417 * Return the value in this TreeMap associated with the supplied key,
418 * or <code>null</code> if the key maps to nothing. NOTE: Since the value
419 * could also be null, you must use containsKey to see if this key
420 * actually maps to something.
422 * @param key the key for which to fetch an associated value
423 * @return what the key maps to, if present
424 * @throws ClassCastException if key is not comparable to elements in the map
425 * @throws NullPointerException if key is null but the comparator does not
426 * tolerate nulls
427 * @see #put(Object, Object)
428 * @see #containsKey(Object)
430 public Object get(Object key)
432 // Exploit fact that nil.value == null.
433 return getNode(key).value;
437 * Returns a view of this Map including all entries with keys less than
438 * <code>toKey</code>. The returned map is backed by the original, so changes
439 * in one appear in the other. The submap will throw an
440 * {@link IllegalArgumentException} for any attempt to access or add an
441 * element beyond the specified cutoff. The returned map does not include
442 * the endpoint; if you want inclusion, pass the successor element.
444 * @param toKey the (exclusive) cutoff point
445 * @return a view of the map less than the cutoff
446 * @throws ClassCastException if <code>toKey</code> is not compatible with
447 * the comparator (or is not Comparable, for natural ordering)
448 * @throws NullPointerException if toKey is null, but the comparator does not
449 * tolerate null elements
451 public SortedMap headMap(Object toKey)
453 return new SubMap(nil, toKey);
457 * Returns a "set view" of this TreeMap's keys. The set is backed by the
458 * TreeMap, so changes in one show up in the other. The set supports
459 * element removal, but not element addition.
461 * @return a set view of the keys
462 * @see #values()
463 * @see #entrySet()
465 public Set keySet()
467 if (keys == null)
468 // Create an AbstractSet with custom implementations of those methods
469 // that can be overriden easily and efficiently.
470 keys = new AbstractSet()
472 public int size()
474 return size;
477 public Iterator iterator()
479 return new TreeIterator(KEYS);
482 public void clear()
484 TreeMap.this.clear();
487 public boolean contains(Object o)
489 return containsKey(o);
492 public boolean remove(Object key)
494 Node n = getNode(key);
495 if (n == nil)
496 return false;
497 removeNode(n);
498 return true;
501 return keys;
505 * Returns the last (highest) key in the map.
507 * @return the last key
508 * @throws NoSuchElementException if the map is empty
510 public Object lastKey()
512 if (root == nil)
513 throw new NoSuchElementException("empty");
514 return lastNode().key;
518 * Puts the supplied value into the Map, mapped by the supplied key.
519 * The value may be retrieved by any object which <code>equals()</code>
520 * this key. NOTE: Since the prior value could also be null, you must
521 * first use containsKey if you want to see if you are replacing the
522 * key's mapping.
524 * @param key the key used to locate the value
525 * @param value the value to be stored in the HashMap
526 * @return the prior mapping of the key, or null if there was none
527 * @throws ClassCastException if key is not comparable to current map keys
528 * @throws NullPointerException if key is null, but the comparator does
529 * not tolerate nulls
530 * @see #get(Object)
531 * @see Object#equals(Object)
533 public Object put(Object key, Object value)
535 Node current = root;
536 Node parent = nil;
537 int comparison = 0;
539 // Find new node's parent.
540 while (current != nil)
542 parent = current;
543 comparison = compare(key, current.key);
544 if (comparison > 0)
545 current = current.right;
546 else if (comparison < 0)
547 current = current.left;
548 else // Key already in tree.
549 return current.setValue(value);
552 // Set up new node.
553 Node n = new Node(key, value, RED);
554 n.parent = parent;
556 // Insert node in tree.
557 modCount++;
558 size++;
559 if (parent == nil)
561 // Special case inserting into an empty tree.
562 root = n;
563 return null;
565 if (comparison > 0)
566 parent.right = n;
567 else
568 parent.left = n;
570 // Rebalance after insert.
571 insertFixup(n);
572 return null;
576 * Copies all elements of the given map into this hashtable. If this table
577 * already has a mapping for a key, the new mapping replaces the current
578 * one.
580 * @param m the map to be hashed into this
581 * @throws ClassCastException if a key in m is not comparable with keys
582 * in the map
583 * @throws NullPointerException if a key in m is null, and the comparator
584 * does not tolerate nulls
586 public void putAll(Map m)
588 Iterator itr = m.entrySet().iterator();
589 int pos = m.size();
590 while (--pos >= 0)
592 Map.Entry e = (Map.Entry) itr.next();
593 put(e.getKey(), e.getValue());
598 * Removes from the TreeMap and returns the value which is mapped by the
599 * supplied key. If the key maps to nothing, then the TreeMap remains
600 * unchanged, and <code>null</code> is returned. NOTE: Since the value
601 * could also be null, you must use containsKey to see if you are
602 * actually removing a mapping.
604 * @param key the key used to locate the value to remove
605 * @return whatever the key mapped to, if present
606 * @throws ClassCastException if key is not comparable to current map keys
607 * @throws NullPointerException if key is null, but the comparator does
608 * not tolerate nulls
610 public Object remove(Object key)
612 Node n = getNode(key);
613 if (n == nil)
614 return null;
615 removeNode(n);
616 return n.value;
620 * Returns the number of key-value mappings currently in this Map.
622 * @return the size
624 public int size()
626 return size;
630 * Returns a view of this Map including all entries with keys greater or
631 * equal to <code>fromKey</code> and less than <code>toKey</code> (a
632 * half-open interval). The returned map is backed by the original, so
633 * changes in one appear in the other. The submap will throw an
634 * {@link IllegalArgumentException} for any attempt to access or add an
635 * element beyond the specified cutoffs. The returned map includes the low
636 * endpoint but not the high; if you want to reverse this behavior on
637 * either end, pass in the successor element.
639 * @param fromKey the (inclusive) low cutoff point
640 * @param toKey the (exclusive) high cutoff point
641 * @return a view of the map between the cutoffs
642 * @throws ClassCastException if either cutoff is not compatible with
643 * the comparator (or is not Comparable, for natural ordering)
644 * @throws NullPointerException if fromKey or toKey is null, but the
645 * comparator does not tolerate null elements
646 * @throws IllegalArgumentException if fromKey is greater than toKey
648 public SortedMap subMap(Object fromKey, Object toKey)
650 return new SubMap(fromKey, toKey);
654 * Returns a view of this Map including all entries with keys greater or
655 * equal to <code>fromKey</code>. The returned map is backed by the
656 * original, so changes in one appear in the other. The submap will throw an
657 * {@link IllegalArgumentException} for any attempt to access or add an
658 * element beyond the specified cutoff. The returned map includes the
659 * endpoint; if you want to exclude it, pass in the successor element.
661 * @param fromKey the (inclusive) low cutoff point
662 * @return a view of the map above the cutoff
663 * @throws ClassCastException if <code>fromKey</code> is not compatible with
664 * the comparator (or is not Comparable, for natural ordering)
665 * @throws NullPointerException if fromKey is null, but the comparator
666 * does not tolerate null elements
668 public SortedMap tailMap(Object fromKey)
670 return new SubMap(fromKey, nil);
674 * Returns a "collection view" (or "bag view") of this TreeMap's values.
675 * The collection is backed by the TreeMap, so changes in one show up
676 * in the other. The collection supports element removal, but not element
677 * addition.
679 * @return a bag view of the values
680 * @see #keySet()
681 * @see #entrySet()
683 public Collection values()
685 if (values == null)
686 // We don't bother overriding many of the optional methods, as doing so
687 // wouldn't provide any significant performance advantage.
688 values = new AbstractCollection()
690 public int size()
692 return size;
695 public Iterator iterator()
697 return new TreeIterator(VALUES);
700 public void clear()
702 TreeMap.this.clear();
705 return values;
709 * Compares two elements by the set comparator, or by natural ordering.
710 * Package visible for use by nested classes.
712 * @param o1 the first object
713 * @param o2 the second object
714 * @throws ClassCastException if o1 and o2 are not mutually comparable,
715 * or are not Comparable with natural ordering
716 * @throws NullPointerException if o1 or o2 is null with natural ordering
718 final int compare(Object o1, Object o2)
720 return (comparator == null
721 ? ((Comparable) o1).compareTo(o2)
722 : comparator.compare(o1, o2));
726 * Maintain red-black balance after deleting a node.
728 * @param node the child of the node just deleted, possibly nil
729 * @param parent the parent of the node just deleted, never nil
731 private void deleteFixup(Node node, Node parent)
733 // if (parent == nil)
734 // throw new InternalError();
735 // If a black node has been removed, we need to rebalance to avoid
736 // violating the "same number of black nodes on any path" rule. If
737 // node is red, we can simply recolor it black and all is well.
738 while (node != root && node.color == BLACK)
740 if (node == parent.left)
742 // Rebalance left side.
743 Node sibling = parent.right;
744 // if (sibling == nil)
745 // throw new InternalError();
746 if (sibling.color == RED)
748 // Case 1: Sibling is red.
749 // Recolor sibling and parent, and rotate parent left.
750 sibling.color = BLACK;
751 parent.color = RED;
752 rotateLeft(parent);
753 sibling = parent.right;
756 if (sibling.left.color == BLACK && sibling.right.color == BLACK)
758 // Case 2: Sibling has no red children.
759 // Recolor sibling, and move to parent.
760 sibling.color = RED;
761 node = parent;
762 parent = parent.parent;
764 else
766 if (sibling.right.color == BLACK)
768 // Case 3: Sibling has red left child.
769 // Recolor sibling and left child, rotate sibling right.
770 sibling.left.color = BLACK;
771 sibling.color = RED;
772 rotateRight(sibling);
773 sibling = parent.right;
775 // Case 4: Sibling has red right child. Recolor sibling,
776 // right child, and parent, and rotate parent left.
777 sibling.color = parent.color;
778 parent.color = BLACK;
779 sibling.right.color = BLACK;
780 rotateLeft(parent);
781 node = root; // Finished.
784 else
786 // Symmetric "mirror" of left-side case.
787 Node sibling = parent.left;
788 // if (sibling == nil)
789 // throw new InternalError();
790 if (sibling.color == RED)
792 // Case 1: Sibling is red.
793 // Recolor sibling and parent, and rotate parent right.
794 sibling.color = BLACK;
795 parent.color = RED;
796 rotateRight(parent);
797 sibling = parent.left;
800 if (sibling.right.color == BLACK && sibling.left.color == BLACK)
802 // Case 2: Sibling has no red children.
803 // Recolor sibling, and move to parent.
804 sibling.color = RED;
805 node = parent;
806 parent = parent.parent;
808 else
810 if (sibling.left.color == BLACK)
812 // Case 3: Sibling has red right child.
813 // Recolor sibling and right child, rotate sibling left.
814 sibling.right.color = BLACK;
815 sibling.color = RED;
816 rotateLeft(sibling);
817 sibling = parent.left;
819 // Case 4: Sibling has red left child. Recolor sibling,
820 // left child, and parent, and rotate parent right.
821 sibling.color = parent.color;
822 parent.color = BLACK;
823 sibling.left.color = BLACK;
824 rotateRight(parent);
825 node = root; // Finished.
829 node.color = BLACK;
833 * Construct a perfectly balanced tree consisting of n "blank" nodes. This
834 * permits a tree to be generated from pre-sorted input in linear time.
836 * @param count the number of blank nodes, non-negative
838 private void fabricateTree(final int count)
840 if (count == 0)
841 return;
843 // We color every row of nodes black, except for the overflow nodes.
844 // I believe that this is the optimal arrangement. We construct the tree
845 // in place by temporarily linking each node to the next node in the row,
846 // then updating those links to the children when working on the next row.
848 // Make the root node.
849 root = new Node(null, null, BLACK);
850 size = count;
851 Node row = root;
852 int rowsize;
854 // Fill each row that is completely full of nodes.
855 for (rowsize = 2; rowsize + rowsize < count; rowsize <<= 1)
857 Node parent = row;
858 Node last = null;
859 for (int i = 0; i < rowsize; i += 2)
861 Node left = new Node(null, null, BLACK);
862 Node right = new Node(null, null, BLACK);
863 left.parent = parent;
864 left.right = right;
865 right.parent = parent;
866 parent.left = left;
867 Node next = parent.right;
868 parent.right = right;
869 parent = next;
870 if (last != null)
871 last.right = left;
872 last = right;
874 row = row.left;
877 // Now do the partial final row in red.
878 int overflow = count - rowsize;
879 Node parent = row;
880 int i;
881 for (i = 0; i < overflow; i += 2)
883 Node left = new Node(null, null, RED);
884 Node right = new Node(null, null, RED);
885 left.parent = parent;
886 right.parent = parent;
887 parent.left = left;
888 Node next = parent.right;
889 parent.right = right;
890 parent = next;
892 // Add a lone left node if necessary.
893 if (i - overflow == 0)
895 Node left = new Node(null, null, RED);
896 left.parent = parent;
897 parent.left = left;
898 parent = parent.right;
899 left.parent.right = nil;
901 // Unlink the remaining nodes of the previous row.
902 while (parent != nil)
904 Node next = parent.right;
905 parent.right = nil;
906 parent = next;
911 * Returns the first sorted node in the map, or nil if empty. Package
912 * visible for use by nested classes.
914 * @return the first node
916 final Node firstNode()
918 // Exploit fact that nil.left == nil.
919 Node node = root;
920 while (node.left != nil)
921 node = node.left;
922 return node;
926 * Return the TreeMap.Node associated with key, or the nil node if no such
927 * node exists in the tree. Package visible for use by nested classes.
929 * @param key the key to search for
930 * @return the node where the key is found, or nil
932 final Node getNode(Object key)
934 Node current = root;
935 while (current != nil)
937 int comparison = compare(key, current.key);
938 if (comparison > 0)
939 current = current.right;
940 else if (comparison < 0)
941 current = current.left;
942 else
943 return current;
945 return current;
949 * Find the "highest" node which is &lt; key. If key is nil, return last
950 * node. Package visible for use by nested classes.
952 * @param key the upper bound, exclusive
953 * @return the previous node
955 final Node highestLessThan(Object key)
957 if (key == nil)
958 return lastNode();
960 Node last = nil;
961 Node current = root;
962 int comparison = 0;
964 while (current != nil)
966 last = current;
967 comparison = compare(key, current.key);
968 if (comparison > 0)
969 current = current.right;
970 else if (comparison < 0)
971 current = current.left;
972 else // Exact match.
973 return predecessor(last);
975 return comparison <= 0 ? predecessor(last) : last;
979 * Maintain red-black balance after inserting a new node.
981 * @param n the newly inserted node
983 private void insertFixup(Node n)
985 // Only need to rebalance when parent is a RED node, and while at least
986 // 2 levels deep into the tree (ie: node has a grandparent). Remember
987 // that nil.color == BLACK.
988 while (n.parent.color == RED && n.parent.parent != nil)
990 if (n.parent == n.parent.parent.left)
992 Node uncle = n.parent.parent.right;
993 // Uncle may be nil, in which case it is BLACK.
994 if (uncle.color == RED)
996 // Case 1. Uncle is RED: Change colors of parent, uncle,
997 // and grandparent, and move n to grandparent.
998 n.parent.color = BLACK;
999 uncle.color = BLACK;
1000 uncle.parent.color = RED;
1001 n = uncle.parent;
1003 else
1005 if (n == n.parent.right)
1007 // Case 2. Uncle is BLACK and x is right child.
1008 // Move n to parent, and rotate n left.
1009 n = n.parent;
1010 rotateLeft(n);
1012 // Case 3. Uncle is BLACK and x is left child.
1013 // Recolor parent, grandparent, and rotate grandparent right.
1014 n.parent.color = BLACK;
1015 n.parent.parent.color = RED;
1016 rotateRight(n.parent.parent);
1019 else
1021 // Mirror image of above code.
1022 Node uncle = n.parent.parent.left;
1023 // Uncle may be nil, in which case it is BLACK.
1024 if (uncle.color == RED)
1026 // Case 1. Uncle is RED: Change colors of parent, uncle,
1027 // and grandparent, and move n to grandparent.
1028 n.parent.color = BLACK;
1029 uncle.color = BLACK;
1030 uncle.parent.color = RED;
1031 n = uncle.parent;
1033 else
1035 if (n == n.parent.left)
1037 // Case 2. Uncle is BLACK and x is left child.
1038 // Move n to parent, and rotate n right.
1039 n = n.parent;
1040 rotateRight(n);
1042 // Case 3. Uncle is BLACK and x is right child.
1043 // Recolor parent, grandparent, and rotate grandparent left.
1044 n.parent.color = BLACK;
1045 n.parent.parent.color = RED;
1046 rotateLeft(n.parent.parent);
1050 root.color = BLACK;
1054 * Returns the last sorted node in the map, or nil if empty.
1056 * @return the last node
1058 private Node lastNode()
1060 // Exploit fact that nil.right == nil.
1061 Node node = root;
1062 while (node.right != nil)
1063 node = node.right;
1064 return node;
1068 * Find the "lowest" node which is &gt;= key. If key is nil, return either
1069 * nil or the first node, depending on the parameter first.
1070 * Package visible for use by nested classes.
1072 * @param key the lower bound, inclusive
1073 * @param first true to return the first element instead of nil for nil key
1074 * @return the next node
1076 final Node lowestGreaterThan(Object key, boolean first)
1078 if (key == nil)
1079 return first ? firstNode() : nil;
1081 Node last = nil;
1082 Node current = root;
1083 int comparison = 0;
1085 while (current != nil)
1087 last = current;
1088 comparison = compare(key, current.key);
1089 if (comparison > 0)
1090 current = current.right;
1091 else if (comparison < 0)
1092 current = current.left;
1093 else
1094 return current;
1096 return comparison > 0 ? successor(last) : last;
1100 * Return the node preceding the given one, or nil if there isn't one.
1102 * @param node the current node, not nil
1103 * @return the prior node in sorted order
1105 private Node predecessor(Node node)
1107 if (node.left != nil)
1109 node = node.left;
1110 while (node.right != nil)
1111 node = node.right;
1112 return node;
1115 Node parent = node.parent;
1116 // Exploit fact that nil.left == nil and node is non-nil.
1117 while (node == parent.left)
1119 node = parent;
1120 parent = node.parent;
1122 return parent;
1126 * Construct a tree from sorted keys in linear time. Package visible for
1127 * use by TreeSet.
1129 * @param s the stream to read from
1130 * @param count the number of keys to read
1131 * @param readValue true to read values, false to insert "" as the value
1132 * @throws ClassNotFoundException if the underlying stream fails
1133 * @throws IOException if the underlying stream fails
1134 * @see #readObject(ObjectInputStream)
1135 * @see TreeSet#readObject(ObjectInputStream)
1137 final void putFromObjStream(ObjectInputStream s, int count,
1138 boolean readValues)
1139 throws IOException, ClassNotFoundException
1141 fabricateTree(count);
1142 Node node = firstNode();
1144 while (--count >= 0)
1146 node.key = s.readObject();
1147 node.value = readValues ? s.readObject() : "";
1148 node = successor(node);
1153 * Construct a tree from sorted keys in linear time, with values of "".
1154 * Package visible for use by TreeSet.
1156 * @param keys the iterator over the sorted keys
1157 * @param count the number of nodes to insert
1158 * @see TreeSet#TreeSet(SortedSet)
1160 final void putKeysLinear(Iterator keys, int count)
1162 fabricateTree(count);
1163 Node node = firstNode();
1165 while (--count >= 0)
1167 node.key = keys.next();
1168 node.value = "";
1169 node = successor(node);
1174 * Deserializes this object from the given stream.
1176 * @param s the stream to read from
1177 * @throws ClassNotFoundException if the underlying stream fails
1178 * @throws IOException if the underlying stream fails
1179 * @serialData the <i>size</i> (int), followed by key (Object) and value
1180 * (Object) pairs in sorted order
1182 private void readObject(ObjectInputStream s)
1183 throws IOException, ClassNotFoundException
1185 s.defaultReadObject();
1186 int size = s.readInt();
1187 putFromObjStream(s, size, true);
1191 * Remove node from tree. This will increment modCount and decrement size.
1192 * Node must exist in the tree. Package visible for use by nested classes.
1194 * @param node the node to remove
1196 final void removeNode(Node node)
1198 Node splice;
1199 Node child;
1201 modCount++;
1202 size--;
1204 // Find splice, the node at the position to actually remove from the tree.
1205 if (node.left == nil)
1207 // Node to be deleted has 0 or 1 children.
1208 splice = node;
1209 child = node.right;
1211 else if (node.right == nil)
1213 // Node to be deleted has 1 child.
1214 splice = node;
1215 child = node.left;
1217 else
1219 // Node has 2 children. Splice is node's predecessor, and we swap
1220 // its contents into node.
1221 splice = node.left;
1222 while (splice.right != nil)
1223 splice = splice.right;
1224 child = splice.left;
1225 node.key = splice.key;
1226 node.value = splice.value;
1229 // Unlink splice from the tree.
1230 Node parent = splice.parent;
1231 if (child != nil)
1232 child.parent = parent;
1233 if (parent == nil)
1235 // Special case for 0 or 1 node remaining.
1236 root = child;
1237 return;
1239 if (splice == parent.left)
1240 parent.left = child;
1241 else
1242 parent.right = child;
1244 if (splice.color == BLACK)
1245 deleteFixup(child, parent);
1249 * Rotate node n to the left.
1251 * @param node the node to rotate
1253 private void rotateLeft(Node node)
1255 Node child = node.right;
1256 // if (node == nil || child == nil)
1257 // throw new InternalError();
1259 // Establish node.right link.
1260 node.right = child.left;
1261 if (child.left != nil)
1262 child.left.parent = node;
1264 // Establish child->parent link.
1265 child.parent = node.parent;
1266 if (node.parent != nil)
1268 if (node == node.parent.left)
1269 node.parent.left = child;
1270 else
1271 node.parent.right = child;
1273 else
1274 root = child;
1276 // Link n and child.
1277 child.left = node;
1278 node.parent = child;
1282 * Rotate node n to the right.
1284 * @param node the node to rotate
1286 private void rotateRight(Node node)
1288 Node child = node.left;
1289 // if (node == nil || child == nil)
1290 // throw new InternalError();
1292 // Establish node.left link.
1293 node.left = child.right;
1294 if (child.right != nil)
1295 child.right.parent = node;
1297 // Establish child->parent link.
1298 child.parent = node.parent;
1299 if (node.parent != nil)
1301 if (node == node.parent.right)
1302 node.parent.right = child;
1303 else
1304 node.parent.left = child;
1306 else
1307 root = child;
1309 // Link n and child.
1310 child.right = node;
1311 node.parent = child;
1315 * Return the node following the given one, or nil if there isn't one.
1316 * Package visible for use by nested classes.
1318 * @param node the current node, not nil
1319 * @return the next node in sorted order
1321 final Node successor(Node node)
1323 if (node.right != nil)
1325 node = node.right;
1326 while (node.left != nil)
1327 node = node.left;
1328 return node;
1331 Node parent = node.parent;
1332 // Exploit fact that nil.right == nil and node is non-nil.
1333 while (node == parent.right)
1335 node = parent;
1336 parent = parent.parent;
1338 return parent;
1342 * Serializes this object to the given stream.
1344 * @param s the stream to write to
1345 * @throws IOException if the underlying stream fails
1346 * @serialData the <i>size</i> (int), followed by key (Object) and value
1347 * (Object) pairs in sorted order
1349 private void writeObject(ObjectOutputStream s) throws IOException
1351 s.defaultWriteObject();
1353 Node node = firstNode();
1354 s.writeInt(size);
1355 while (node != nil)
1357 s.writeObject(node.key);
1358 s.writeObject(node.value);
1359 node = successor(node);
1364 * Iterate over HashMap's entries. This implementation is parameterized
1365 * to give a sequential view of keys, values, or entries.
1367 * @author Eric Blake <ebb9@email.byu.edu>
1369 private final class TreeIterator implements Iterator
1372 * The type of this Iterator: {@link #KEYS}, {@link #VALUES},
1373 * or {@link #ENTRIES}.
1375 private final int type;
1376 /** The number of modifications to the backing Map that we know about. */
1377 private int knownMod = modCount;
1378 /** The last Entry returned by a next() call. */
1379 private Node last;
1380 /** The next entry that should be returned by next(). */
1381 private Node next;
1383 * The last node visible to this iterator. This is used when iterating
1384 * on a SubMap.
1386 private final Node max;
1389 * Construct a new TreeIterator with the supplied type.
1390 * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
1392 TreeIterator(int type)
1394 // FIXME gcj cannot handle this. Bug java/4695
1395 // this(type, firstNode(), nil);
1396 this.type = type;
1397 this.next = firstNode();
1398 this.max = nil;
1402 * Construct a new TreeIterator with the supplied type. Iteration will
1403 * be from "first" (inclusive) to "max" (exclusive).
1405 * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES}
1406 * @param first where to start iteration, nil for empty iterator
1407 * @param max the cutoff for iteration, nil for all remaining nodes
1409 TreeIterator(int type, Node first, Node max)
1411 this.type = type;
1412 this.next = first;
1413 this.max = max;
1417 * Returns true if the Iterator has more elements.
1418 * @return true if there are more elements
1419 * @throws ConcurrentModificationException if the TreeMap was modified
1421 public boolean hasNext()
1423 if (knownMod != modCount)
1424 throw new ConcurrentModificationException();
1425 return next != max;
1429 * Returns the next element in the Iterator's sequential view.
1430 * @return the next element
1431 * @throws ConcurrentModificationException if the TreeMap was modified
1432 * @throws NoSuchElementException if there is none
1434 public Object next()
1436 if (knownMod != modCount)
1437 throw new ConcurrentModificationException();
1438 if (next == max)
1439 throw new NoSuchElementException();
1440 last = next;
1441 next = successor(last);
1443 if (type == VALUES)
1444 return last.value;
1445 else if (type == KEYS)
1446 return last.key;
1447 return last;
1451 * Removes from the backing TreeMap the last element which was fetched
1452 * with the <code>next()</code> method.
1453 * @throws ConcurrentModificationException if the TreeMap was modified
1454 * @throws IllegalStateException if called when there is no last element
1456 public void remove()
1458 if (knownMod != modCount)
1459 throw new ConcurrentModificationException();
1460 if (last == null)
1461 throw new IllegalStateException();
1463 removeNode(last);
1464 last = null;
1465 knownMod++;
1467 } // class TreeIterator
1470 * Implementation of {@link #subMap(Object, Object)} and other map
1471 * ranges. This class provides a view of a portion of the original backing
1472 * map, and throws {@link IllegalArgumentException} for attempts to
1473 * access beyond that range.
1475 * @author Eric Blake <ebb9@email.byu.edu>
1477 private final class SubMap extends AbstractMap implements SortedMap
1480 * The lower range of this view, inclusive, or nil for unbounded.
1481 * Package visible for use by nested classes.
1483 final Object minKey;
1486 * The upper range of this view, exclusive, or nil for unbounded.
1487 * Package visible for use by nested classes.
1489 final Object maxKey;
1492 * The cache for {@link #entrySet()}.
1494 private Set entries;
1497 * Create a SubMap representing the elements between minKey (inclusive)
1498 * and maxKey (exclusive). If minKey is nil, SubMap has no lower bound
1499 * (headMap). If maxKey is nil, the SubMap has no upper bound (tailMap).
1501 * @param minKey the lower bound
1502 * @param maxKey the upper bound
1503 * @throws IllegalArgumentException if minKey &gt; maxKey
1505 SubMap(Object minKey, Object maxKey)
1507 if (minKey != nil && maxKey != nil && compare(minKey, maxKey) > 0)
1508 throw new IllegalArgumentException("fromKey > toKey");
1509 this.minKey = minKey;
1510 this.maxKey = maxKey;
1514 * Check if "key" is in within the range bounds for this SubMap. The
1515 * lower ("from") SubMap range is inclusive, and the upper ("to") bound
1516 * is exclusive. Package visible for use by nested classes.
1518 * @param key the key to check
1519 * @return true if the key is in range
1521 final boolean keyInRange(Object key)
1523 return ((minKey == nil || compare(key, minKey) >= 0)
1524 && (maxKey == nil || compare(key, maxKey) < 0));
1527 public void clear()
1529 Node next = lowestGreaterThan(minKey, true);
1530 Node max = lowestGreaterThan(maxKey, false);
1531 while (next != max)
1533 Node current = next;
1534 next = successor(current);
1535 removeNode(current);
1539 public Comparator comparator()
1541 return comparator;
1544 public boolean containsKey(Object key)
1546 return keyInRange(key) && TreeMap.this.containsKey(key);
1549 public boolean containsValue(Object value)
1551 Node node = lowestGreaterThan(minKey, true);
1552 Node max = lowestGreaterThan(maxKey, false);
1553 while (node != max)
1555 if (equals(value, node.getValue()))
1556 return true;
1557 node = successor(node);
1559 return false;
1562 public Set entrySet()
1564 if (entries == null)
1565 // Create an AbstractSet with custom implementations of those methods
1566 // that can be overriden easily and efficiently.
1567 entries = new AbstractSet()
1569 public int size()
1571 return SubMap.this.size();
1574 public Iterator iterator()
1576 Node first = lowestGreaterThan(minKey, true);
1577 Node max = lowestGreaterThan(maxKey, false);
1578 return new TreeIterator(ENTRIES, first, max);
1581 public void clear()
1583 SubMap.this.clear();
1586 public boolean contains(Object o)
1588 if (! (o instanceof Map.Entry))
1589 return false;
1590 Map.Entry me = (Map.Entry) o;
1591 Object key = me.getKey();
1592 if (! keyInRange(key))
1593 return false;
1594 Node n = getNode(key);
1595 return n != nil && AbstractSet.equals(me.getValue(), n.value);
1598 public boolean remove(Object o)
1600 if (! (o instanceof Map.Entry))
1601 return false;
1602 Map.Entry me = (Map.Entry) o;
1603 Object key = me.getKey();
1604 if (! keyInRange(key))
1605 return false;
1606 Node n = getNode(key);
1607 if (n != nil && AbstractSet.equals(me.getValue(), n.value))
1609 removeNode(n);
1610 return true;
1612 return false;
1615 return entries;
1618 public Object firstKey()
1620 Node node = lowestGreaterThan(minKey, true);
1621 if (node == nil || ! keyInRange(node.key))
1622 throw new NoSuchElementException();
1623 return node.key;
1626 public Object get(Object key)
1628 if (keyInRange(key))
1629 return TreeMap.this.get(key);
1630 return null;
1633 public SortedMap headMap(Object toKey)
1635 if (! keyInRange(toKey))
1636 throw new IllegalArgumentException("key outside range");
1637 return new SubMap(minKey, toKey);
1640 public Set keySet()
1642 if (this.keys == null)
1643 // Create an AbstractSet with custom implementations of those methods
1644 // that can be overriden easily and efficiently.
1645 this.keys = new AbstractSet()
1647 public int size()
1649 return SubMap.this.size();
1652 public Iterator iterator()
1654 Node first = lowestGreaterThan(minKey, true);
1655 Node max = lowestGreaterThan(maxKey, false);
1656 return new TreeIterator(KEYS, first, max);
1659 public void clear()
1661 SubMap.this.clear();
1664 public boolean contains(Object o)
1666 if (! keyInRange(o))
1667 return false;
1668 return getNode(o) != nil;
1671 public boolean remove(Object o)
1673 if (! keyInRange(o))
1674 return false;
1675 Node n = getNode(o);
1676 if (n != nil)
1678 removeNode(n);
1679 return true;
1681 return false;
1684 return this.keys;
1687 public Object lastKey()
1689 Node node = highestLessThan(maxKey);
1690 if (node == nil || ! keyInRange(node.key))
1691 throw new NoSuchElementException();
1692 return node.key;
1695 public Object put(Object key, Object value)
1697 if (! keyInRange(key))
1698 throw new IllegalArgumentException("Key outside range");
1699 return TreeMap.this.put(key, value);
1702 public Object remove(Object key)
1704 if (keyInRange(key))
1705 return TreeMap.this.remove(key);
1706 return null;
1709 public int size()
1711 Node node = lowestGreaterThan(minKey, true);
1712 Node max = lowestGreaterThan(maxKey, false);
1713 int count = 0;
1714 while (node != max)
1716 count++;
1717 node = successor(node);
1719 return count;
1722 public SortedMap subMap(Object fromKey, Object toKey)
1724 if (! keyInRange(fromKey) || ! keyInRange(toKey))
1725 throw new IllegalArgumentException("key outside range");
1726 return new SubMap(fromKey, toKey);
1729 public SortedMap tailMap(Object fromKey)
1731 if (! keyInRange(fromKey))
1732 throw new IllegalArgumentException("key outside range");
1733 return new SubMap(fromKey, maxKey);
1736 public Collection values()
1738 if (this.values == null)
1739 // Create an AbstractCollection with custom implementations of those
1740 // methods that can be overriden easily and efficiently.
1741 this.values = new AbstractCollection()
1743 public int size()
1745 return SubMap.this.size();
1748 public Iterator iterator()
1750 Node first = lowestGreaterThan(minKey, true);
1751 Node max = lowestGreaterThan(maxKey, false);
1752 return new TreeIterator(VALUES, first, max);
1755 public void clear()
1757 SubMap.this.clear();
1760 return this.keys;
1762 } // class SubMap
1763 } // class TreeMap