RBTreeMap.java
0001 /*
0002  *  RBTreeMap.java
0003  *
0004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
0005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
0006  *
0007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
0008  *  software, licenced under the GNU Library General Public License,
0009  *  Version 2, June 1991 (in the distribution as file licence.html,
0010  *  and also available at http://gate.ac.uk/gate/licence.html).
0011  *
0012  *  Valentin Tablan, Jan/2000, modified from Sun sources
0013  *
0014  *  $Id: RBTreeMap.java 12006 2009-12-01 17:24:28Z thomas_heitz $
0015  */
0016 
0017 package gate.util;
0018 import java.util.*;
0019 
0020 /** Slightly modified implementation of java.util.TreeMap in order to return the
0021   * closest neighbours in the case of a failed search.
0022   */
0023 public class RBTreeMap extends AbstractMap
0024                implements SortedMap, Cloneable, java.io.Serializable
0025 {
0026   /** Debug flag */
0027   private static final boolean DEBUG = false;
0028 
0029   /** Freeze the serialization UID. */
0030   static final long serialVersionUID = -1454324265766936618L;
0031 
0032   /**
0033     * The Comparator used to maintain order in this RBTreeMap, or
0034     * null if this RBTreeMap uses its elements natural ordering.
0035     *
0036     @serial
0037     */
0038   private Comparator comparator = null;
0039 
0040    private transient Entry root = null;
0041 
0042   /**
0043     * The number of entries in the tree
0044     */
0045   private transient int size = 0;
0046 
0047   /**
0048     * The number of structural modifications to the tree.
0049     */
0050   private transient int modCount = 0;
0051 
0052   private void incrementSize()   { modCount++; size++; }
0053   private void decrementSize()   { modCount++; size--; }
0054 
0055   /**
0056     * Constructs a new, empty map, sorted according to the keys' natural
0057     * order.  All keys inserted into the map must implement the
0058     <tt>Comparable</tt> interface.  Furthermore, all such keys must be
0059     <i>mutually comparable</i><tt>k1.compareTo(k2)</tt> must not throw a
0060     * ClassCastException for any elements <tt>k1</tt> and <tt>k2</tt> in the
0061     * map.  If the user attempts to put a key into the map that violates this
0062     * constraint (for example, the user attempts to put a string key into a
0063     * map whose keys are integers), the <tt>put(Object key, Object
0064     * value)</tt> call will throw a <tt>ClassCastException</tt>.
0065     *
0066     @see Comparable
0067     */
0068   public RBTreeMap() {
0069   }
0070 
0071   /**
0072     * Constructs a new, empty map, sorted according to the given comparator.
0073     * All keys inserted into the map must be <i>mutually comparable</i> by
0074     * the given comparator: <tt>comparator.compare(k1, k2)</tt> must not
0075     * throw a <tt>ClassCastException</tt> for any keys <tt>k1</tt> and
0076     <tt>k2</tt> in the map.  If the user attempts to put a key into the
0077     * map that violates this constraint, the <tt>put(Object key, Object
0078     * value)</tt> call will throw a <tt>ClassCastException</tt>.
0079     */
0080   public RBTreeMap(Comparator c) {
0081     this.comparator = c;
0082   }
0083 
0084   /**
0085     * Constructs a new map containing the same mappings as the given map,
0086     * sorted according to the keys' <i>natural order</i>.  All keys inserted
0087     * into the new map must implement the <tt>Comparable</tt> interface.
0088     * Furthermore, all such keys must be <i>mutually comparable</i>:
0089     <tt>k1.compareTo(k2)</tt> must not throw a <tt>ClassCastException</tt>
0090     * for any elements <tt>k1</tt> and <tt>k2</tt> in the map.  This method
0091     * runs in n*log(n) time.
0092     *
0093     @throws    ClassCastException the keys in t are not Comparable, or
0094     * are not mutually comparable.
0095     */
0096   public RBTreeMap(Map m) {
0097     putAll(m);
0098   }
0099 
0100   /**
0101     * Constructs a new map containing the same mappings as the given
0102     <tt>SortedMap</tt>, sorted according to the same ordering.  This method
0103     * runs in linear time.
0104     */
0105   public RBTreeMap(SortedMap m) {
0106       comparator = m.comparator();
0107       try {
0108           buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
0109       catch (java.io.IOException cannotHappen) {
0110       catch (ClassNotFoundException cannotHappen) {
0111       }
0112   }
0113 
0114 
0115   // Query Operations
0116 
0117   /**
0118     * Returns the number of key-value mappings in this map.
0119     *
0120     @return the number of key-value mappings in this map.
0121     */
0122   public int size() {
0123     return size;
0124   }
0125 
0126   /**
0127     * Returns <tt>true</tt> if this map contains a mapping for the specified
0128     * key.
0129     *
0130     @param key key whose presence in this map is to be tested.
0131     *
0132     @return <tt>true</tt> if this map contains a mapping for the
0133     *            specified key.
0134     @throws ClassCastException if the key cannot be compared with the keys
0135     *      currently in the map.
0136     @throws NullPointerException key is <tt>null</tt> and this map uses
0137     *      natural ordering, or its comparator does not tolerate
0138     *            <tt>null</tt> keys.
0139     */
0140   public boolean containsKey(Object key) {
0141     return getEntry(key!= null;
0142   }
0143 
0144   /**
0145     * Returns <tt>true</tt> if this map maps one or more keys to the
0146     * specified value.  More formally, returns <tt>true</tt> if and only if
0147     * this map contains at least one mapping to a value <tt>v</tt> such
0148     * that <tt>(value==null ? v==null : value.equals(v))</tt>.  This
0149     * operation will probably require time linear in the Map size for most
0150     * implementations of Map.
0151     *
0152     @param value value whose presence in this Map is to be tested.
0153     @since JDK1.2
0154     */
0155   public boolean containsValue(Object value) {
0156       return (value==null ? valueSearchNull(root)
0157               : valueSearchNonNull(root, value));
0158   }
0159 
0160   private boolean valueSearchNull(Entry n) {
0161       if (n.value == null)
0162           return true;
0163 
0164       // Check left and right subtrees for value
0165       return (n.left  != null && valueSearchNull(n.left)) ||
0166              (n.right != null && valueSearchNull(n.right));
0167   }
0168 
0169   private boolean valueSearchNonNull(Entry n, Object value) {
0170       // Check this node for the value
0171       if (value.equals(n.value))
0172           return true;
0173 
0174       // Check left and right subtrees for value
0175       return (n.left  != null && valueSearchNonNull(n.left, value)) ||
0176              (n.right != null && valueSearchNonNull(n.right, value));
0177   }
0178 
0179   /**
0180     * Returns a pair of values: (glb,lub).
0181     * If the given key is found in the map then glb=lub=the value associated
0182     * with the given key.
0183     * If the key is not in the map:
0184     * glb=the value associated with the greatest key in the map that is lower
0185     * than the given key; or null if the given key is smaller than any key in
0186     * the map.
0187     * lub=the value associated with the smaller key in the map that is greater
0188     * than the given key; or null the given key is greater than any key in the
0189     * map.
0190     * If the map is empty it returns (null,null).
0191     */
0192   public Object[] getClosestMatch(Object key){
0193     if (root==null)return new Object[]{null,null};
0194 
0195     Entry lub=getCeilEntry(key);
0196 
0197     if(lub==null){//greatest key in set is still smaller then parameter "key"
0198       return new Object[]{lastEntry().value,null};
0199     };
0200 
0201     int cmp=compare(key,lub.key);
0202 
0203     if (cmp==0){return new Object[]{lub.value,lub.value};}
0204     else {
0205       Entry prec=getPrecedingEntry(lub.key);
0206       if (prec == nullreturn new Object[]{null,lub.value};
0207       else return new Object[]{prec.value,lub.value};
0208     }
0209   }
0210 
0211   /** Returns the value associated to the next key in the map if an exact match
0212     * doesn't exist. If there is an exact match, the method will return the
0213     * value associated to the given key.
0214     @param key the key for wich the look-up will be done.
0215     @return the value associated to the given key or the next available
0216     * value
0217     */
0218   public Object getNextOf(Object key){
0219     if (root==nullreturn null;
0220     Entry lub=getCeilEntry(key);
0221     if (lub == nullreturn null;
0222     return lub.value;
0223   }
0224 
0225   /**
0226     * Returns the value to which this map maps the specified key.  Returns
0227     <tt>null</tt> if the map contains no mapping for this key.  A return
0228     * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
0229     * map contains no mapping for the key; it's also possible that the map
0230     * explicitly maps the key to <tt>null</tt>.  The <tt>containsKey</tt>
0231     * operation may be used to distinguish these two cases.
0232     *
0233     @param key key whose associated value is to be returned.
0234     @return the value to which this map maps the specified key, or
0235     *         <tt>null</tt> if the map contains no mapping for the key.
0236     @throws    ClassCastException key cannot be compared with the keys
0237     *      currently in the map.
0238     @throws NullPointerException key is <tt>null</tt> and this map uses
0239     *      natural ordering, or its comparator does not tolerate
0240     *      <tt>null</tt> keys.
0241     *
0242     @see #containsKey(Object)
0243     */
0244   public Object get(Object key) {
0245     Entry p = getEntry(key);
0246     return (p==null null : p.value);
0247   }
0248 
0249   /**
0250     * Returns the comparator used to order this map, or <tt>null</tt> if this
0251     * map uses its keys' natural order.
0252     *
0253     @return the comparator associated with this sorted map, or
0254     *          <tt>null</tt> if it uses its keys' natural sort method.
0255     */
0256   public Comparator comparator() {
0257       return comparator;
0258   }
0259 
0260   /**
0261     * Returns the first (lowest) key currently in this sorted map.
0262     *
0263     @return the first (lowest) key currently in this sorted map.
0264     @throws    NoSuchElementException Map is empty.
0265     */
0266   public Object firstKey() {
0267       return key(firstEntry());
0268   }
0269 
0270   /**
0271     * Returns the last (highest) key currently in this sorted map.
0272     *
0273     @return the last (highest) key currently in this sorted map.
0274     @throws    NoSuchElementException Map is empty.
0275     */
0276   public Object lastKey() {
0277       return key(lastEntry());
0278   }
0279 
0280   /**
0281     * Copies all of the mappings from the specified map to this map.  These
0282     * mappings replace any mappings that this map had for any of the keys
0283     * currently in the specified map.
0284     *
0285     @param map Mappings to be stored in this map.
0286     @throws    ClassCastException class of a key or value in the specified
0287     *             map prevents it from being stored in this map.
0288     *
0289     @throws NullPointerException this map does not permit <tt>null</tt>
0290     *            keys and a specified key is <tt>null</tt>.
0291     */
0292   public void putAll(Map map) {
0293       int mapSize = map.size();
0294       if (size==&& mapSize!=&& map instanceof SortedMap) {
0295           Comparator c = ((SortedMap)map).comparator();
0296           if (c == comparator || (c != null && c.equals(comparator))) {
0297             ++modCount;
0298             try {
0299                 buildFromSorted(mapSize, map.entrySet().iterator(),
0300                                 null, null);
0301             catch (java.io.IOException cannotHappen) {
0302             catch (ClassNotFoundException cannotHappen) {
0303             }
0304             return;
0305           }
0306       }
0307       super.putAll(map);
0308   }
0309 
0310   /**
0311     * Returns this map's entry for the given key, or <tt>null</tt> if the map
0312     * does not contain an entry for the key.
0313     *
0314     @return this map's entry for the given key, or <tt>null</tt> if the map
0315     *          does not contain an entry for the key.
0316     @throws ClassCastException if the key cannot be compared with the keys
0317     *      currently in the map.
0318     @throws NullPointerException key is <tt>null</tt> and this map uses
0319     *      natural order, or its comparator does not tolerate *
0320     *      <tt>null</tt> keys.
0321     */
0322   private Entry getEntry(Object key) {
0323     Entry p = root;
0324     while (p != null) {
0325         int cmp = compare(key,p.key);
0326         if (cmp == 0)
0327       return p;
0328         else if (cmp < 0)
0329       p = p.left;
0330         else
0331       p = p.right;
0332     }
0333     return null;
0334   }
0335 
0336 
0337   /**
0338     * Gets the entry corresponding to the specified key; if no such entry
0339     * exists, returns the entry for the least key greater than the specified
0340     * key; if no such entry exists (i.e., the greatest key in the Tree is less
0341     * than the specified key), returns <tt>null</tt>.
0342     */
0343   private Entry getCeilEntry(Object key) {
0344     Entry p = root;
0345     if (p==null)
0346         return null;
0347 
0348     while (true) {
0349         int cmp = compare(key, p.key);
0350         if (cmp == 0) {
0351       return p;
0352         else if (cmp < 0) {
0353       if (p.left != null)
0354           p = p.left;
0355       else
0356           return p;
0357         else {
0358       if (p.right != null) {
0359           p = p.right;
0360       else {
0361           Entry parent = p.parent;
0362           Entry ch = p;
0363           while (parent != null && ch == parent.right) {
0364         ch = parent;
0365         parent = parent.parent;
0366           }
0367           return parent;
0368       }
0369         }
0370     }
0371   }
0372 
0373   /**
0374     * Returns the entry for the greatest key less than the specified key; if
0375     * no such entry exists (i.e., the least key in the Tree is greater than
0376     * the specified key), returns <tt>null</tt>.
0377     */
0378   private Entry getPrecedingEntry(Object key) {
0379     Entry p = root;
0380     if (p==null)return null;
0381 
0382     while (true) {
0383       int cmp = compare(key, p.key);
0384       if (cmp > 0) {
0385         if (p.right != nullp = p.right;
0386         else return p;
0387         }else{
0388           if (p.left != null) {
0389             p = p.left;
0390           else {
0391             Entry parent = p.parent;
0392             Entry ch = p;
0393             while (parent != null && ch == parent.left) {
0394               ch = parent;
0395               parent = parent.parent;
0396             }
0397             return parent;
0398           }
0399         }
0400     }//while true
0401   }
0402 
0403   /**
0404     * Returns the key corresonding to the specified Entry.  Throw
0405     * NoSuchElementException if the Entry is <tt>null</tt>.
0406     */
0407   private static Object key(Entry e) {
0408       if (e==null)
0409           throw new NoSuchElementException();
0410       return e.key;
0411   }
0412 
0413   /**
0414     * Associates the specified value with the specified key in this map.
0415     * If the map previously contained a mapping for this key, the old
0416     * value is replaced.
0417     *
0418     @param key key with which the specified value is to be associated.
0419     @param value value to be associated with the specified key.
0420     *
0421     @return previous value associated with specified key, or <tt>null</tt>
0422     *         if there was no mapping for key.  A <tt>null</tt> return can
0423     *         also indicate that the map previously associated <tt>null</tt>
0424     *         with the specified key.
0425     @throws    ClassCastException key cannot be compared with the keys
0426     *      currently in the map.
0427     @throws NullPointerException key is <tt>null</tt> and this map uses
0428     *      natural order, or its comparator does not tolerate
0429     *      <tt>null</tt> keys.
0430     */
0431   public Object put(Object key, Object value) {
0432     Entry t = root;
0433 
0434     if (t == null) {
0435         incrementSize();
0436         root = new Entry(key, value, null);
0437         return null;
0438     }
0439 
0440     while (true) {
0441         int cmp = compare(key, t.key);
0442         if (cmp == 0) {
0443       return t.setValue(value);
0444         else if (cmp < 0) {
0445       if (t.left != null) {
0446           t = t.left;
0447       else {
0448           incrementSize();
0449           t.left = new Entry(key, value, t);
0450           fixAfterInsertion(t.left);
0451           return null;
0452       }
0453         else // cmp > 0
0454       if (t.right != null) {
0455           t = t.right;
0456       else {
0457           incrementSize();
0458           t.right = new Entry(key, value, t);
0459           fixAfterInsertion(t.right);
0460           return null;
0461       }
0462         }
0463     }
0464   }
0465 
0466   /**
0467     * Removes the mapping for this key from this RBTreeMap if present.
0468     *
0469     @return previous value associated with specified key, or <tt>null</tt>
0470     *         if there was no mapping for key.  A <tt>null</tt> return can
0471     *         also indicate that the map previously associated
0472     *         <tt>null</tt> with the specified key.
0473     *
0474     @throws    ClassCastException key cannot be compared with the keys
0475     *      currently in the map.
0476     @throws NullPointerException key is <tt>null</tt> and this map uses
0477     *      natural order, or its comparator does not tolerate
0478     *      <tt>null</tt> keys.
0479     */
0480   public Object remove(Object key) {
0481     Entry p = getEntry(key);
0482     if (p == null)
0483         return null;
0484 
0485     Object oldValue = p.value;
0486     deleteEntry(p);
0487     return oldValue;
0488   }
0489 
0490   /**
0491     * Removes all mappings from this RBTreeMap.
0492     */
0493   public void clear() {
0494     modCount++;
0495     size = 0;
0496     root = null;
0497   }
0498 
0499   /**
0500     * Returns a shallow copy of this <tt>RBTreeMap</tt> instance. (The keys and
0501     * values themselves are not cloned.)
0502     *
0503     @return a shallow copy of this Map.
0504     */
0505   public Object clone() {
0506     return new RBTreeMap(this);
0507   }
0508 
0509 
0510   // Views
0511 
0512   /**
0513     * These fields are initialized to contain an instance of the appropriate
0514     * view the first time this view is requested.  The views are stateless,
0515     * so there's no reason to create more than one of each.
0516     */
0517   private transient Set    keySet = null;
0518   private transient Set    entrySet = null;
0519   private transient Collection  values = null;
0520 
0521   /**
0522     * Returns a Set view of the keys contained in this map.  The set's
0523     * iterator will return the keys in ascending order.  The map is backed by
0524     * this <tt>RBTreeMap</tt> instance, so changes to this map are reflected in
0525     * the Set, and vice-versa.  The Set supports element removal, which
0526     * removes the corresponding mapping from the map, via the
0527     <tt>Iterator.remove</tt><tt>Set.remove</tt><tt>removeAll</tt>,
0528     <tt>retainAll</tt>, and <tt>clear</tt> operations.  It does not support
0529     * the <tt>add</tt> or <tt>addAll</tt> operations.
0530     *
0531     @return a set view of the keys contained in this RBTreeMap.
0532     */
0533   public Set keySet() {
0534     if (keySet == null) {
0535       keySet = new AbstractSet() {
0536 
0537         public java.util.Iterator iterator() {
0538             return new Iterator(KEYS);
0539         }
0540 
0541         public int size() {
0542           return RBTreeMap.this.size();
0543         }
0544 
0545         public boolean contains(Object o) {
0546           return containsKey(o);
0547         }
0548 
0549         public boolean remove(Object o) {
0550           return RBTreeMap.this.remove(o!= null;
0551         }
0552 
0553         public void clear() {
0554           RBTreeMap.this.clear();
0555         }
0556       };
0557     }
0558     return keySet;
0559   }
0560 
0561   /**
0562     * Returns a collection view of the values contained in this map.  The
0563     * collection's iterator will return the values in the order that their
0564     * corresponding keys appear in the tree.  The collection is backed by
0565     * this <tt>RBTreeMap</tt> instance, so changes to this map are reflected in
0566     * the collection, and vice-versa.  The collection supports element
0567     * removal, which removes the corresponding mapping from the map through
0568     * the <tt>Iterator.remove</tt><tt>Collection.remove</tt>,
0569     <tt>removeAll</tt><tt>retainAll</tt>, and <tt>clear</tt> operations.
0570     * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
0571     *
0572     @return a collection view of the values contained in this map.
0573     */
0574   public Collection values() {
0575     if (values == null) {
0576       values = new AbstractCollection() {
0577         public java.util.Iterator iterator() {
0578             return new Iterator(VALUES);
0579         }
0580 
0581         public int size() {
0582             return RBTreeMap.this.size();
0583         }
0584 
0585         public boolean contains(Object o) {
0586             for (Entry e = firstEntry(); e != null; e = successor(e))
0587                 if (valEquals(e.getValue(), o))
0588                     return true;
0589             return false;
0590         }
0591 
0592         public boolean remove(Object o) {
0593           for (Entry e = firstEntry(); e != null; e = successor(e)) {
0594             if (valEquals(e.getValue(), o)) {
0595                 deleteEntry(e);
0596                 return true;
0597             }
0598           }
0599           return false;
0600         }
0601 
0602         public void clear() {
0603             RBTreeMap.this.clear();
0604         }
0605       };
0606     }
0607     return values;
0608   }
0609 
0610   /**
0611     * Returns a set view of the mappings contained in this map.  The set's
0612     * iterator returns the mappings in ascending key order.  Each element in
0613     * the returned set is a <tt>Map.Entry</tt>.  The set is backed by this
0614     * map, so changes to this map are reflected in the set, and vice-versa.
0615     * The set supports element removal, which removes the corresponding
0616     * mapping from the RBTreeMap, through the <tt>Iterator.remove</tt>,
0617     <tt>Set.remove</tt><tt>removeAll</tt><tt>retainAll</tt> and
0618     <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
0619     <tt>addAll</tt> operations.
0620     *
0621     @return a set view of the mappings contained in this map.
0622     @see Map.Entry
0623     */
0624   public Set entrySet() {
0625     if (entrySet == null) {
0626       entrySet = new AbstractSet() {
0627         public java.util.Iterator iterator() {
0628           return new Iterator(ENTRIES);
0629         }
0630 
0631         public boolean contains(Object o) {
0632           if (!(instanceof Map.Entry))
0633               return false;
0634           Map.Entry entry = (Map.Entry)o;
0635           Object value = entry.getValue();
0636           Entry p = getEntry(entry.getKey());
0637           return p != null && valEquals(p.getValue(), value);
0638         }
0639 
0640         public boolean remove(Object o) {
0641           if (!(instanceof Map.Entry))
0642               return false;
0643           Map.Entry entry = (Map.Entry)o;
0644           Object value = entry.getValue();
0645           Entry p = getEntry(entry.getKey());
0646           if (p != null && valEquals(p.getValue(), value)) {
0647               deleteEntry(p);
0648               return true;
0649           }
0650           return false;
0651         }
0652 
0653         public int size() {
0654             return RBTreeMap.this.size();
0655         }
0656 
0657         public void clear() {
0658             RBTreeMap.this.clear();
0659         }
0660       };
0661     }
0662     return entrySet;
0663   }
0664 
0665   /**
0666     * Returns a view of the portion of this map whose keys range from
0667     <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive.  (If
0668     <tt>fromKey</tt> and <tt>toKey</tt> are equal, the returned sorted map
0669     * is empty.)  The returned sorted map is backed by this map, so changes
0670     * in the returned sorted map are reflected in this map, and vice-versa.
0671     * The returned sorted map supports all optional map operations.<p>
0672     *
0673     * The sorted map returned by this method will throw an
0674     <tt>IllegalArgumentException</tt> if the user attempts to insert a key
0675     * less than <tt>fromKey</tt> or greater than or equal to
0676     <tt>toKey</tt>.<p>
0677     *
0678     * Note: this method always returns a <i>half-open range</i> (which
0679     * includes its low endpoint but not its high endpoint).  If you need a
0680     <i>closed range</i> (which includes both endpoints), and the key type
0681     * allows for calculation of the successor a given key, merely request the
0682     * subrange from <tt>lowEndpoint</tt> to <tt>successor(highEndpoint)</tt>.
0683     * For example, suppose that <tt>m</tt> is a sorted map whose keys are
0684     * strings.  The following idiom obtains a view containing all of the
0685     * key-value mappings in <tt>m</tt> whose keys are between <tt>low</tt>
0686     * and <tt>high</tt>, inclusive:
0687     *       <pre>    SortedMap sub = m.submap(low, high+"\0");</pre>
0688     * A similar technique can be used to generate an <i>open range</i> (which
0689     * contains neither endpoint).  The following idiom obtains a view
0690     * containing all of the key-value mappings in <tt>m</tt> whose keys are
0691     * between <tt>low</tt> and <tt>high</tt>, exclusive:
0692     *       <pre>    SortedMap sub = m.subMap(low+"\0", high);</pre>
0693     *
0694     @param fromKey low endpoint (inclusive) of the subMap.
0695     @param toKey high endpoint (exclusive) of the subMap.
0696     *
0697     @return a view of the portion of this map whose keys range from
0698     *          <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive.
0699     *
0700     @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is
0701     *      <tt>null</tt> and this map uses natural order, or its
0702     *      comparator does not tolerate <tt>null</tt> keys.
0703     *
0704     @throws IllegalArgumentException if <tt>fromKey</tt> is greater than
0705     *            <tt>toKey</tt>.
0706     */
0707   public SortedMap subMap(Object fromKey, Object toKey) {
0708     return new SubMap(fromKey, toKey);
0709   }
0710 
0711   /**
0712     * Returns a view of the portion of this map whose keys are strictly less
0713     * than <tt>toKey</tt>.  The returned sorted map is backed by this map, so
0714     * changes in the returned sorted map are reflected in this map, and
0715     * vice-versa.  The returned sorted map supports all optional map
0716     * operations.<p>
0717     *
0718     * The sorted map returned by this method will throw an
0719     <tt>IllegalArgumentException</tt> if the user attempts to insert a key
0720     * greater than or equal to <tt>toKey</tt>.<p>
0721     *
0722     * Note: this method always returns a view that does not contain its
0723     * (high) endpoint.  If you need a view that does contain this endpoint,
0724     * and the key type allows for calculation of the successor a given key,
0725     * merely request a headMap bounded by <tt>successor(highEndpoint)</tt>.
0726     * For example, suppose that suppose that <tt>m</tt> is a sorted map whose
0727     * keys are strings.  The following idiom obtains a view containing all of
0728     * the key-value mappings in <tt>m</tt> whose keys are less than or equal
0729     * to <tt>high</tt>:
0730     <pre>
0731     *     SortedMap head = m.headMap(high+"\0");
0732     </pre>
0733     *
0734     @param toKey high endpoint (exclusive) of the headMap.
0735     @return a view of the portion of this map whose keys are strictly
0736     *          less than <tt>toKey</tt>.
0737     @throws NullPointerException if <tt>toKey</tt> is <tt>null</tt> and
0738     *      this map uses natural order, or its comparator does * not
0739     *      tolerate <tt>null</tt> keys.
0740     */
0741   public SortedMap headMap(Object toKey) {
0742     return new SubMap(toKey, true);
0743   }
0744 
0745   /**
0746     * Returns a view of the portion of this map whose keys are greater than
0747     * or equal to <tt>fromKey</tt>.  The returned sorted map is backed by
0748     * this map, so changes in the returned sorted map are reflected in this
0749     * map, and vice-versa.  The returned sorted map supports all optional map
0750     * operations.<p>
0751     *
0752     * The sorted map returned by this method will throw an
0753     <tt>IllegalArgumentException</tt> if the user attempts to insert a key
0754     * less than <tt>fromKey</tt>.<p>
0755     *
0756     * Note: this method always returns a view that contains its (low)
0757     * endpoint.  If you need a view that does not contain this endpoint, and
0758     * the element type allows for calculation of the successor a given value,
0759     * merely request a tailMap bounded by <tt>successor(lowEndpoint)</tt>.
0760     * For For example, suppose that suppose that <tt>m</tt> is a sorted map
0761     * whose keys are strings.  The following idiom obtains a view containing
0762     * all of the key-value mappings in <tt>m</tt> whose keys are strictly
0763     * greater than <tt>low</tt><pre>
0764     *     SortedMap tail = m.tailMap(low+"\0");
0765     </pre>
0766     *
0767     @param fromKey low endpoint (inclusive) of the tailMap.
0768     @return a view of the portion of this map whose keys are greater
0769     *          than or equal to <tt>fromKey</tt>.
0770     @throws    NullPointerException fromKey is <tt>null</tt> and this
0771     *      map uses natural ordering, or its comparator does
0772     *            not tolerate <tt>null</tt> keys.
0773     */
0774   public SortedMap tailMap(Object fromKey) {
0775     return new SubMap(fromKey, false);
0776   }
0777 
0778   private class SubMap extends AbstractMap
0779          implements SortedMap, java.io.Serializable {
0780 
0781     // fromKey is significant only if fromStart is false.  Similarly,
0782     // toKey is significant only if toStart is false.
0783     private boolean fromStart = false, toEnd = false;
0784     private Object  fromKey,           toKey;
0785 
0786     SubMap(Object fromKey, Object toKey) {
0787       if (compare(fromKey, toKey0)
0788         throw new IllegalArgumentException("fromKey > toKey");
0789       this.fromKey = fromKey;
0790       this.toKey = toKey;
0791     }
0792 
0793     SubMap(Object key, boolean headMap) {
0794       if (headMap) {
0795           fromStart = true;
0796           toKey = key;
0797       else {
0798           toEnd = true;
0799           fromKey = key;
0800       }
0801     }
0802 
0803     SubMap(boolean fromStart, Object fromKey, boolean toEnd, Object toKey){
0804       this.fromStart = fromStart;
0805       this.fromKey= fromKey;
0806       this.toEnd = toEnd;
0807       this.toKey = toKey;
0808     }
0809 
0810     public boolean isEmpty() {
0811       return entrySet.isEmpty();
0812     }
0813 
0814     public boolean containsKey(Object key) {
0815       return inRange(key&& RBTreeMap.this.containsKey(key);
0816     }
0817 
0818     public Object get(Object key) {
0819       if (!inRange(key))
0820         return null;
0821       return RBTreeMap.this.get(key);
0822     }
0823 
0824     public Object put(Object key, Object value) {
0825       if (!inRange(key))
0826         throw new IllegalArgumentException("key out of range");
0827       return RBTreeMap.this.put(key, value);
0828     }
0829 
0830     public Comparator comparator() {
0831         return comparator;
0832     }
0833 
0834     public Object firstKey() {
0835         return key(fromStart ? firstEntry() : getCeilEntry(fromKey));
0836     }
0837 
0838     public Object lastKey() {
0839         return key(toEnd ? lastEntry() : getPrecedingEntry(toKey));
0840     }
0841 
0842     private transient Set entrySet = new EntrySetView();
0843 
0844     public Set entrySet() {
0845         return entrySet;
0846     }
0847 
0848     private class EntrySetView extends AbstractSet {
0849       private transient int size = -1, sizeModCount;
0850 
0851       public int size() {
0852         if (size == -|| sizeModCount != RBTreeMap.this.modCount) {
0853           size = 0;  sizeModCount = RBTreeMap.this.modCount;
0854           java.util.Iterator i = iterator();
0855           while (i.hasNext()) {
0856             size++;
0857             i.next();
0858           }
0859         }
0860         return size;
0861       // size
0862 
0863       public boolean isEmpty() {
0864         return !iterator().hasNext();
0865       }// isEmpty
0866 
0867       public boolean contains(Object o) {
0868         if (!(instanceof Map.Entry))
0869           return false;
0870 
0871         Map.Entry entry = (Map.Entry)o;
0872         Object key = entry.getKey();
0873         if (!inRange(key))
0874           return false;
0875         RBTreeMap.Entry node = getEntry(key);
0876         return node != null &&
0877                  valEquals(node.getValue(), entry.getValue());
0878       // contains
0879 
0880       public boolean remove(Object o) {
0881         if (!(instanceof Map.Entry))
0882           return false;
0883         Map.Entry entry = (Map.Entry)o;
0884         Object key = entry.getKey();
0885         if (!inRange(key))
0886           return false;
0887         RBTreeMap.Entry node = getEntry(key);
0888         if (node!=null && valEquals(node.getValue(),entry.getValue())){
0889           deleteEntry(node);
0890           return true;
0891         }
0892         return false;
0893       }
0894 
0895       public java.util.Iterator iterator() {
0896         return new Iterator(
0897                   (fromStart ? firstEntry() : getCeilEntry(fromKey)),
0898                   (toEnd     ? null        : getCeilEntry(toKey)));
0899       }
0900     // EntrySetView
0901 
0902     public SortedMap subMap(Object fromKey, Object toKey) {
0903       if (!inRange(fromKey))
0904         throw new IllegalArgumentException("fromKey out of range");
0905       if (!inRange2(toKey))
0906         throw new IllegalArgumentException("toKey out of range");
0907       return new SubMap(fromKey, toKey);
0908     }
0909 
0910     public SortedMap headMap(Object toKey) {
0911       if (!inRange2(toKey))
0912         throw new IllegalArgumentException("toKey out of range");
0913       return new SubMap(fromStart, fromKey, false, toKey);
0914     }
0915 
0916     public SortedMap tailMap(Object fromKey) {
0917       if (!inRange(fromKey))
0918         throw new IllegalArgumentException("fromKey out of range");
0919       return new SubMap(false, fromKey, toEnd, toKey);
0920     }
0921 
0922     private boolean inRange(Object key) {
0923       return (fromStart || compare(key, fromKey>= 0&&
0924                      (toEnd     || compare(key, toKey)   <  0);
0925     }
0926 
0927     // This form allows the high endpoint (as well as all legit keys)
0928     private boolean inRange2(Object key) {
0929       return (fromStart || compare(key, fromKey>= 0&&
0930                  (toEnd     || compare(key, toKey)   <= 0);
0931     }
0932     static final long serialVersionUID = 4333473260468321526L;
0933   // SubMap
0934 
0935   // Types of Iterators
0936   private static final int KEYS = 0;
0937 
0938   private static final int VALUES = 1;
0939 
0940   private static final int ENTRIES = 2;
0941 
0942   /**
0943     * RBTreeMap Iterator.
0944     */
0945   private class Iterator implements java.util.Iterator {
0946     private int type;
0947 
0948     private int expectedModCount = RBTreeMap.this.modCount;
0949 
0950     private Entry lastReturned = null;
0951 
0952     private Entry next;
0953 
0954     private Entry firstExcluded = null;
0955 
0956     Iterator(int type) {
0957       this.type = type;
0958       next = firstEntry();
0959     }
0960 
0961     Iterator(Entry first, Entry firstExcluded) {
0962       type = ENTRIES;
0963       next = first;
0964       this.firstExcluded = firstExcluded;
0965     }
0966 
0967     public boolean hasNext() {
0968       return next != firstExcluded;
0969     //hasNext
0970 
0971     public Object next() {
0972       if (next == firstExcluded)
0973         throw new NoSuchElementException();
0974 
0975       if (modCount != expectedModCount)
0976         throw new ConcurrentModificationException();
0977 
0978       lastReturned = next;
0979       next = successor(next);
0980       return (type == KEYS ? lastReturned.key :
0981         (type == VALUES ? lastReturned.value : lastReturned));
0982     // next
0983 
0984     public void remove() {
0985       if (lastReturned == null)
0986         throw new IllegalStateException();
0987 
0988       if (modCount != expectedModCount)
0989         throw new ConcurrentModificationException();
0990 
0991       deleteEntry(lastReturned);
0992       expectedModCount++;
0993       lastReturned = null;
0994     // remove
0995   //Iterator
0996 
0997   /**
0998     * Compares two keys using the correct comparison method for this RBTreeMap.
0999     */
1000   private int compare(Object k1, Object k2) {
1001     return (comparator==null ((Comparable)k1).compareTo(k2)
1002        : comparator.compare(k1, k2));
1003   }
1004 
1005   /**
1006     * Test two values  for equality.  Differs from o1.equals(o2) only in
1007     * that it copes with with <tt>null</tt> o1 properly.
1008     */
1009   private static boolean valEquals(Object o1, Object o2) {
1010     return (o1==null ? o2==null : o1.equals(o2));
1011   }
1012 
1013   private static final boolean RED   = false;
1014 
1015   private static final boolean BLACK = true;
1016 
1017   /**
1018     * Node in the Tree.  Doubles as a means to pass key-value pairs back to
1019     * user (see Map.Entry).
1020     */
1021 
1022   static class Entry implements Map.Entry {
1023     Object key;
1024     Object value;
1025     Entry left = null;
1026     Entry right = null;
1027     Entry parent;
1028     boolean color = BLACK;
1029 
1030     /** Make a new cell with given key, value, and parent, and with
1031       <tt>null</tt> child links, and BLACK color.
1032       */
1033     Entry(Object key, Object value, Entry parent) {
1034       this.key = key;
1035       this.value = value;
1036       this.parent = parent;
1037     }
1038 
1039     /**
1040       * Returns the key.
1041       *
1042       @return the key.
1043       */
1044     public Object getKey() {
1045         return key;
1046     }
1047 
1048     /**
1049       * Returns the value associated with the key.
1050       *
1051       @return the value associated with the key.
1052       */
1053     public Object getValue() {
1054         return value;
1055     }
1056 
1057     /**
1058       * Replaces the value currently associated with the key with the given
1059       * value.
1060       *
1061       @return the value associated with the key before this method was
1062       * called.
1063       */
1064     public Object setValue(Object value) {
1065         Object oldValue = this.value;
1066         this.value = value;
1067         return oldValue;
1068     }
1069 
1070     public boolean equals(Object o) {
1071         if (!(instanceof Map.Entry))
1072       return false;
1073         Map.Entry e = (Map.Entry)o;
1074 
1075         return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
1076     // equals
1077 
1078     public int hashCode() {
1079         int keyHash = (key==null : key.hashCode());
1080         int valueHash = (value==null : value.hashCode());
1081         return keyHash ^ valueHash;
1082     // hashCode
1083 
1084     public String toString() {
1085         return key + "=" + value;
1086     }
1087   // Entry
1088 
1089   /**
1090     * Returns the first Entry in the RBTreeMap (according to the RBTreeMap's
1091     * key-sort function).  Returns null if the RBTreeMap is empty.
1092     */
1093   private Entry firstEntry() {
1094     Entry p = root;
1095     if (p != null)
1096       while (p.left != null)
1097         p = p.left;
1098     return p;
1099   }
1100 
1101   /**
1102     * Returns the last Entry in the RBTreeMap (according to the RBTreeMap's
1103     * key-sort function).  Returns null if the RBTreeMap is empty.
1104     */
1105   private Entry lastEntry() {
1106     Entry p = root;
1107     if (p != null)
1108       while (p.right != null)
1109         p = p.right;
1110     return p;
1111   }
1112 
1113   /**
1114     * Returns the successor of the specified Entry, or null if no such.
1115     */
1116   private Entry successor(Entry t) {
1117     if (t == null)
1118       return null;
1119     else if (t.right != null) {
1120       Entry p = t.right;
1121       while (p.left != null)
1122         p = p.left;
1123       return p;
1124     else {
1125       Entry p = t.parent;
1126       Entry ch = t;
1127       while (p != null && ch == p.right) {
1128         ch = p;
1129         p = p.parent;
1130       }
1131       return p;
1132     }
1133   // successor
1134 
1135   /**
1136     * Balancing operations.
1137     *
1138     * Implementations of rebalancings during insertion and deletion are
1139     * slightly different than the CLR version.  Rather than using dummy
1140     * nilnodes, we use a set of accessors that deal properly with null.  They
1141     * are used to avoid messiness surrounding nullness checks in the main
1142     * algorithms.
1143     */
1144 
1145   private static boolean colorOf(Entry p) {
1146     return (p == null ? BLACK : p.color);
1147   }
1148 
1149   private static Entry  parentOf(Entry p) {
1150     return (p == null null: p.parent);
1151   }
1152 
1153   private static void setColor(Entry p, boolean c) {
1154     if (p != null)  p.color = c;
1155   }
1156 
1157   private static Entry  leftOf(Entry p) {
1158     return (p == null)null: p.left;
1159   }
1160 
1161   private static Entry  rightOf(Entry p) {
1162     return (p == null)null: p.right;
1163   }
1164 
1165   /** From CLR **/
1166   private void rotateLeft(Entry p) {
1167     Entry r = p.right;
1168     p.right = r.left;
1169 
1170     if (r.left != null)
1171       r.left.parent = p;
1172     r.parent = p.parent;
1173 
1174     if (p.parent == null)
1175       root = r;
1176     else if (p.parent.left == p)
1177       p.parent.left = r;
1178     else
1179       p.parent.right = r;
1180     r.left = p;
1181     p.parent = r;
1182   }
1183 
1184   /** From CLR **/
1185   private void rotateRight(Entry p) {
1186     Entry l = p.left;
1187     p.left = l.right;
1188 
1189     if (l.right != nulll.right.parent = p;
1190     l.parent = p.parent;
1191 
1192     if (p.parent == null)
1193         root = l;
1194     else if (p.parent.right == p)
1195         p.parent.right = l;
1196     else p.parent.left = l;
1197 
1198     l.right = p;
1199     p.parent = l;
1200   }
1201 
1202 
1203   /** From CLR **/
1204   private void fixAfterInsertion(Entry x) {
1205     x.color = RED;
1206 
1207     while (x != null && x != root && x.parent.color == RED) {
1208       if (parentOf(x== leftOf(parentOf(parentOf(x)))) {
1209         Entry y = rightOf(parentOf(parentOf(x)));
1210         if (colorOf(y== RED) {
1211           setColor(parentOf(x), BLACK);
1212           setColor(y, BLACK);
1213           setColor(parentOf(parentOf(x)), RED);
1214           x = parentOf(parentOf(x));
1215         else {
1216           if (x == rightOf(parentOf(x))) {
1217             x = parentOf(x);
1218             rotateLeft(x);
1219           }
1220           setColor(parentOf(x), BLACK);
1221           setColor(parentOf(parentOf(x)), RED);
1222           if (parentOf(parentOf(x)) != null)
1223             rotateRight(parentOf(parentOf(x)));
1224         }
1225       else {
1226         Entry y = leftOf(parentOf(parentOf(x)));
1227         if (colorOf(y== RED) {
1228             setColor(parentOf(x), BLACK);
1229             setColor(y, BLACK);
1230             setColor(parentOf(parentOf(x)), RED);
1231             x = parentOf(parentOf(x));
1232         else {
1233           if (x == leftOf(parentOf(x))) {
1234             x = parentOf(x);
1235             rotateRight(x);
1236           }
1237           setColor(parentOf(x),  BLACK);
1238           setColor(parentOf(parentOf(x)), RED);
1239           if (parentOf(parentOf(x)) != null)
1240             rotateLeft(parentOf(parentOf(x)));
1241         }
1242       }
1243     }
1244     root.color = BLACK;
1245   // fixAfterInsertion
1246 
1247   /**
1248     * Delete node p, and then rebalance the tree.
1249     */
1250   private void deleteEntry(Entry p) {
1251     decrementSize();
1252 
1253     // If strictly internal, first swap position with successor.
1254     if (p.left != null && p.right != null) {
1255         Entry s = successor(p);
1256         swapPosition(s, p);
1257     }
1258 
1259     // Start fixup at replacement node, if it exists.
1260     Entry replacement = (p.left != null ? p.left : p.right);
1261 
1262     if (replacement != null) {
1263       // Link replacement to parent
1264       replacement.parent = p.parent;
1265       if (p.parent == null)
1266         root = replacement;
1267       else if (p == p.parent.left)
1268         p.parent.left  = replacement;
1269       else
1270         p.parent.right = replacement;
1271 
1272     // Null out links so they are OK to use by fixAfterDeletion.
1273     p.left = p.right = p.parent = null;
1274 
1275     // Fix replacement
1276     if (p.color == BLACK)
1277       fixAfterDeletion(replacement);
1278     else if (p.parent == null) { // return if we are the only node.
1279       root = null;
1280     else //  No children. Use self as phantom replacement and unlink.
1281       if (p.color == BLACK)
1282         fixAfterDeletion(p);
1283 
1284       if (p.parent != null) {
1285         if (p == p.parent.left)
1286           p.parent.left = null;
1287         else if (p == p.parent.right)
1288           p.parent.right = null;
1289         p.parent = null;
1290       }
1291     }
1292   // deleteEntry
1293 
1294   /** From CLR **/
1295   private void fixAfterDeletion(Entry x) {
1296     while (x != root && colorOf(x== BLACK) {
1297       if (x == leftOf(parentOf(x))) {
1298         Entry sib = rightOf(parentOf(x));
1299 
1300         if (colorOf(sib== RED) {
1301           setColor(sib, BLACK);
1302           setColor(parentOf(x), RED);
1303           rotateLeft(parentOf(x));
1304           sib = rightOf(parentOf(x));
1305         }
1306 
1307         if (colorOf(leftOf(sib))  == BLACK &&
1308             colorOf(rightOf(sib)) == BLACK) {
1309           setColor(sib,  RED);
1310           x = parentOf(x);
1311         else {
1312           if (colorOf(rightOf(sib)) == BLACK) {
1313             setColor(leftOf(sib), BLACK);
1314             setColor(sib, RED);
1315             rotateRight(sib);
1316             sib = rightOf(parentOf(x));
1317           }
1318           setColor(sib, colorOf(parentOf(x)));
1319           setColor(parentOf(x), BLACK);
1320           setColor(rightOf(sib), BLACK);
1321           rotateLeft(parentOf(x));
1322           x = root;
1323         }
1324       else // symmetric
1325         Entry sib = leftOf(parentOf(x));
1326 
1327         if (colorOf(sib== RED) {
1328           setColor(sib, BLACK);
1329           setColor(parentOf(x), RED);
1330           rotateRight(parentOf(x));
1331           sib = leftOf(parentOf(x));
1332         }
1333 
1334         if (colorOf(rightOf(sib)) == BLACK &&
1335           colorOf(leftOf(sib)) == BLACK) {
1336           setColor(sib,  RED);
1337           x = parentOf(x);
1338         else {
1339           if (colorOf(leftOf(sib)) == BLACK) {
1340             setColor(rightOf(sib), BLACK);
1341             setColor(sib, RED);
1342             rotateLeft(sib);
1343             sib = leftOf(parentOf(x));
1344           }
1345           setColor(sib, colorOf(parentOf(x)));
1346           setColor(parentOf(x), BLACK);
1347           setColor(leftOf(sib), BLACK);
1348           rotateRight(parentOf(x));
1349           x = root;
1350         }
1351       }
1352     }
1353     setColor(x, BLACK);
1354   // fixAfterDeletion
1355 
1356   /**
1357     * Swap the linkages of two nodes in a tree.
1358     */
1359   private void swapPosition(Entry x, Entry y) {
1360     // Save initial values.
1361     Entry px = x.parent, lx = x.left, rx = x.right;
1362     Entry py = y.parent, ly = y.left, ry = y.right;
1363     boolean xWasLeftChild = px != null && x == px.left;
1364     boolean yWasLeftChild = py != null && y == py.left;
1365 
1366     // Swap, handling special cases of one being the other's parent.
1367     if (x == py) {  // x was y's parent
1368       x.parent = y;
1369 
1370       if (yWasLeftChild) {
1371         y.left = x;
1372         y.right = rx;
1373       else {
1374         y.right = x;
1375         y.left = lx;
1376       }
1377     else {
1378       x.parent = py;
1379 
1380       if (py != null) {
1381         if (yWasLeftChild)
1382           py.left = x;
1383         else
1384           py.right = x;
1385       }
1386       y.left = lx;
1387       y.right = rx;
1388     }
1389 
1390     if (y == px) { // y was x's parent
1391       y.parent = x;
1392       if (xWasLeftChild) {
1393         x.left = y;
1394         x.right = ry;
1395       else {
1396         x.right = y;
1397         x.left = ly;
1398       }
1399     else {
1400       y.parent = px;
1401       if (px != null) {
1402         if (xWasLeftChild)
1403           px.left = y;
1404         else
1405           px.right = y;
1406       }
1407       x.left = ly;
1408       x.right = ry;
1409     }
1410 
1411     // Fix children's parent pointers
1412     if (x.left != null)
1413       x.left.parent = x;
1414 
1415     if (x.right != null)
1416       x.right.parent = x;
1417 
1418     if (y.left != null)
1419       y.left.parent = y;
1420 
1421     if (y.right != null)
1422       y.right.parent = y;
1423 
1424     // Swap colors
1425     boolean c = x.color;
1426     x.color = y.color;
1427     y.color = c;
1428 
1429     // Check if root changed
1430     if (root == x)
1431         root = y;
1432     else if (root == y)
1433         root = x;
1434   // swapPosition
1435 
1436 
1437 
1438 
1439   /**
1440     * Save the state of the <tt>RBTreeMap</tt> instance to a stream (i.e.,
1441     * serialize it).
1442     *
1443     @serialData The <i>size</i> of the RBTreeMap (the number of key-value
1444     *       mappings) is emitted (int), followed by the key (Object)
1445     *       and value (Object) for each key-value mapping represented
1446     *       by the RBTreeMap. The key-value mappings are emitted in
1447     *       key-order (as determined by the RBTreeMap's Comparator,
1448     *       or by the keys' natural ordering if the RBTreeMap has no
1449     *             Comparator).
1450     */
1451   private void writeObject(java.io.ObjectOutputStream s)
1452       throws java.io.IOException {
1453 
1454     // Write out the Comparator and any hidden stuff
1455     s.defaultWriteObject();
1456 
1457     // Write out size (number of Mappings)
1458     s.writeInt(size);
1459 
1460           // Write out keys and values (alternating)
1461     for (java.util.Iterator i = entrySet().iterator(); i.hasNext()) {
1462               Entry e = (Entry)i.next();
1463               s.writeObject(e.key);
1464               s.writeObject(e.value);
1465     }
1466   // writeObject
1467 
1468 
1469 
1470   /**
1471     * Reconstitute the <tt>RBTreeMap</tt> instance from a stream (i.e.,
1472     * deserialize it).
1473     */
1474   private void readObject(final java.io.ObjectInputStream s)
1475       throws java.io.IOException, ClassNotFoundException {
1476 
1477     // Read in the Comparator and any hidden stuff
1478     s.defaultReadObject();
1479 
1480     // Read in size
1481     int size = s.readInt();
1482 
1483     buildFromSorted(size, null, s, null);
1484   // readObject
1485 
1486   /** Intended to be called only from TreeSet.readObject */
1487   void readTreeSet(int size, java.io.ObjectInputStream s, Object defaultVal)
1488       throws java.io.IOException, ClassNotFoundException {
1489     buildFromSorted(size, null, s, defaultVal);
1490   }
1491 
1492   /** Intended to be called only from TreeSet.addAll */
1493   void addAllForTreeSet(SortedSet set, Object defaultVal) {
1494     try {
1495       buildFromSorted(set.size(), set.iterator(), null, defaultVal);
1496     catch (java.io.IOException cannotHappen) {
1497     catch (ClassNotFoundException cannotHappen) {
1498     }
1499   }
1500 
1501 
1502   /**
1503     * Linear time tree building algorithm from sorted data.  Can accept keys
1504     * and/or values from iterator or stream. This leads to too many
1505     * parameters, but seems better than alternatives.  The four formats
1506     * that this method accepts are:
1507     *
1508     *    1) An iterator of Map.Entries.  (it != null, defaultVal == null).
1509     *    2) An iterator of keys.         (it != null, defaultVal != null).
1510     *    3) A stream of alternating serialized keys and values.
1511     *            (it == null, defaultVal == null).
1512     *    4) A stream of serialized keys. (it == null, defaultVal != null).
1513     *
1514     * It is assumed that the comparator of the RBTreeMap is already set prior
1515     * to calling this method.
1516     *
1517     @param size the number of keys (or key-value pairs) to be read from
1518     *        the iterator or stream.
1519     @param it If non-null, new entries are created from entries
1520     *        or keys read from this iterator.
1521     @param str If non-null, new entries are created from keys and
1522     *        possibly values read from this stream in serialized form.
1523     *        Exactly one of it and str should be non-null.
1524     @param defaultVal if non-null, this default value is used for
1525     *        each value in the map.  If null, each value is read from
1526     *        iterator or stream, as described above.
1527     @throws IOException propagated from stream reads. This cannot
1528     *         occur if str is null.
1529     @throws ClassNotFoundException propagated from readObject.
1530     *         This cannot occur if str is null.
1531     */
1532   private void buildFromSorted(int size, java.util.Iterator it,
1533                                 java.io.ObjectInputStream str,
1534                                 Object defaultVal)
1535     throws  java.io.IOException, ClassNotFoundException {
1536 
1537     this.size = size;
1538     root = buildFromSorted(00, size-1, computeRedLevel(size),
1539                              it, str, defaultVal);
1540   // buildFromSorted
1541 
1542   /**
1543     * Recursive "helper method" that does the real work of the
1544     * of the previous method.  Identically named parameters have
1545     * identical definitions.  Additional parameters are documented below.
1546     * It is assumed that the comparator and size fields of the RBTreeMap are
1547     * already set prior to calling this method.  (It ignores both fields.)
1548     *
1549     @param level the current level of tree. Initial call should be 0.
1550     @param lo the first element index of this subtree. Initial should be 0.
1551     @param hi the last element index of this subtree.  Initial should be
1552     *        size-1.
1553     @param redLevel the level at which nodes should be red.
1554     *        Must be equal to computeRedLevel for tree of this size.
1555     */
1556   private static Entry buildFromSorted(int level, int lo, int hi,
1557                                        int redLevel,
1558                                        java.util.Iterator it,
1559                                        java.io.ObjectInputStream str,
1560                                        Object defaultVal)
1561     throws  java.io.IOException, ClassNotFoundException {
1562     /*
1563      * Strategy: The root is the middlemost element. To get to it, we
1564      * have to first recursively construct the entire left subtree,
1565      * so as to grab all of its elements. We can then proceed with right
1566      * subtree.
1567      *
1568      * The lo and hi arguments are the minimum and maximum
1569      * indices to pull out of the iterator or stream for current subtree.
1570      * They are not actually indexed, we just proceed sequentially,
1571      * ensuring that items are extracted in corresponding order.
1572      */
1573 
1574     if (hi < loreturn null;
1575 
1576     int mid = (lo + hi2;
1577 
1578     Entry left  = null;
1579     if (lo < mid)
1580       left = buildFromSorted(level+1, lo, mid - 1, redLevel,
1581                                it, str, defaultVal);
1582 
1583     // extract key and/or value from iterator or stream
1584     Object key;
1585     Object value;
1586 
1587     if (it != null) { // use iterator
1588 
1589       if (defaultVal==null) {
1590         Map.Entry entry = (Map.Entryit.next();
1591         key = entry.getKey();
1592         value = entry.getValue();
1593       else {
1594         key = it.next();
1595         value = defaultVal;
1596       }
1597     else // use stream
1598       key = str.readObject();
1599       value = (defaultVal != null ? defaultVal : str.readObject());
1600     }
1601 
1602     Entry middle =  new Entry(key, value, null);
1603 
1604     // color nodes in non-full bottommost level red
1605     if (level == redLevel)
1606       middle.color = RED;
1607 
1608     if (left != null) {
1609       middle.left = left;
1610       left.parent = middle;
1611     }
1612 
1613     if (mid < hi) {
1614       Entry right = buildFromSorted(level+1, mid+1, hi, redLevel,
1615                                     it, str, defaultVal);
1616       middle.right = right;
1617       right.parent = middle;
1618     }
1619 
1620     return middle;
1621 
1622   // Entry buildFromSorted
1623 
1624   /**
1625     * Find the level down to which to assign all nodes BLACK.  This is the
1626     * last `full' level of the complete binary tree produced by
1627     * buildTree. The remaining nodes are colored RED. (This makes a `nice'
1628     * set of color assignments wrt future insertions.) This level number is
1629     * computed by finding the number of splits needed to reach the zeroeth
1630     * node.  (The answer is ~lg(N), but in any case must be computed by same
1631     * quick O(lg(N)) loop.)
1632     */
1633   private static int computeRedLevel(int sz) {
1634     int level = 0;
1635     for (int m = sz - 1; m >= 0; m = m / 1)
1636         level++;
1637     return level;
1638   }
1639 
1640 // class RBTreeMap