1   /*
2    *  RBTreeMap.java
3    *
4    *  Copyright (c) 1998-2005, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Valentin Tablan, Jan/2000, modified from Sun sources
12   *
13   *  $Id: RBTreeMap.java,v 1.18 2005/01/11 13:51:37 ian Exp $
14   */
15  
16  package gate.util;
17  import java.util.*;
18  
19  /** Slightly modified implementation of java.util.TreeMap in order to return the
20    * closest neighbours in the case of a failed search.
21    */
22  public class RBTreeMap extends AbstractMap
23                 implements SortedMap, Cloneable, java.io.Serializable
24  {
25    /** Debug flag */
26    private static final boolean DEBUG = false;
27  
28    /** Freeze the serialization UID. */
29    static final long serialVersionUID = -1454324265766936618L;
30  
31    /**
32      * The Comparator used to maintain order in this RBTreeMap, or
33      * null if this RBTreeMap uses its elements natural ordering.
34      *
35      * @serial
36      */
37    private Comparator comparator = null;
38  
39     private transient Entry root = null;
40  
41    /**
42      * The number of entries in the tree
43      */
44    private transient int size = 0;
45  
46    /**
47      * The number of structural modifications to the tree.
48      */
49    private transient int modCount = 0;
50  
51    private void incrementSize()   { modCount++; size++; }
52    private void decrementSize()   { modCount++; size--; }
53  
54    /**
55      * Constructs a new, empty map, sorted according to the keys' natural
56      * order.  All keys inserted into the map must implement the
57      * <tt>Comparable</tt> interface.  Furthermore, all such keys must be
58      * <i>mutually comparable</i>: <tt>k1.compareTo(k2)</tt> must not throw a
59      * ClassCastException for any elements <tt>k1</tt> and <tt>k2</tt> in the
60      * map.  If the user attempts to put a key into the map that violates this
61      * constraint (for example, the user attempts to put a string key into a
62      * map whose keys are integers), the <tt>put(Object key, Object
63      * value)</tt> call will throw a <tt>ClassCastException</tt>.
64      *
65      * @see Comparable
66      */
67    public RBTreeMap() {
68    }
69  
70    /**
71      * Constructs a new, empty map, sorted according to the given comparator.
72      * All keys inserted into the map must be <i>mutually comparable</i> by
73      * the given comparator: <tt>comparator.compare(k1, k2)</tt> must not
74      * throw a <tt>ClassCastException</tt> for any keys <tt>k1</tt> and
75      * <tt>k2</tt> in the map.  If the user attempts to put a key into the
76      * map that violates this constraint, the <tt>put(Object key, Object
77      * value)</tt> call will throw a <tt>ClassCastException</tt>.
78      */
79    public RBTreeMap(Comparator c) {
80      this.comparator = c;
81    }
82  
83    /**
84      * Constructs a new map containing the same mappings as the given map,
85      * sorted according to the keys' <i>natural order</i>.  All keys inserted
86      * into the new map must implement the <tt>Comparable</tt> interface.
87      * Furthermore, all such keys must be <i>mutually comparable</i>:
88      * <tt>k1.compareTo(k2)</tt> must not throw a <tt>ClassCastException</tt>
89      * for any elements <tt>k1</tt> and <tt>k2</tt> in the map.  This method
90      * runs in n*log(n) time.
91      *
92      * @throws    ClassCastException the keys in t are not Comparable, or
93      * are not mutually comparable.
94      */
95    public RBTreeMap(Map m) {
96      putAll(m);
97    }
98  
99    /**
100     * Constructs a new map containing the same mappings as the given
101     * <tt>SortedMap</tt>, sorted according to the same ordering.  This method
102     * runs in linear time.
103     */
104   public RBTreeMap(SortedMap m) {
105       comparator = m.comparator();
106       try {
107           buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
108       } catch (java.io.IOException cannotHappen) {
109       } catch (ClassNotFoundException cannotHappen) {
110       }
111   }
112 
113 
114   // Query Operations
115 
116   /**
117     * Returns the number of key-value mappings in this map.
118     *
119     * @return the number of key-value mappings in this map.
120     */
121   public int size() {
122     return size;
123   }
124 
125   /**
126     * Returns <tt>true</tt> if this map contains a mapping for the specified
127     * key.
128     *
129     * @param key key whose presence in this map is to be tested.
130     *
131     * @return <tt>true</tt> if this map contains a mapping for the
132     *            specified key.
133     * @throws ClassCastException if the key cannot be compared with the keys
134     *     currently in the map.
135     * @throws NullPointerException key is <tt>null</tt> and this map uses
136     *     natural ordering, or its comparator does not tolerate
137     *            <tt>null</tt> keys.
138     */
139   public boolean containsKey(Object key) {
140     return getEntry(key) != null;
141   }
142 
143   /**
144     * Returns <tt>true</tt> if this map maps one or more keys to the
145     * specified value.  More formally, returns <tt>true</tt> if and only if
146     * this map contains at least one mapping to a value <tt>v</tt> such
147     * that <tt>(value==null ? v==null : value.equals(v))</tt>.  This
148     * operation will probably require time linear in the Map size for most
149     * implementations of Map.
150     *
151     * @param value value whose presence in this Map is to be tested.
152     * @since JDK1.2
153     */
154   public boolean containsValue(Object value) {
155       return (value==null ? valueSearchNull(root)
156               : valueSearchNonNull(root, value));
157   }
158 
159   private boolean valueSearchNull(Entry n) {
160       if (n.value == null)
161           return true;
162 
163       // Check left and right subtrees for value
164       return (n.left  != null && valueSearchNull(n.left)) ||
165              (n.right != null && valueSearchNull(n.right));
166   }
167 
168   private boolean valueSearchNonNull(Entry n, Object value) {
169       // Check this node for the value
170       if (value.equals(n.value))
171           return true;
172 
173       // Check left and right subtrees for value
174       return (n.left  != null && valueSearchNonNull(n.left, value)) ||
175              (n.right != null && valueSearchNonNull(n.right, value));
176   }
177 
178   /**
179     * Returns a pair of values: (glb,lub).
180     * If the given key is found in the map then glb=lub=the value associated
181     * with the given key.
182     * If the key is not in the map:
183     * glb=the value associated with the greatest key in the map that is lower
184     * than the given key; or null if the given key is smaller than any key in
185     * the map.
186     * lub=the value associated with the smaller key in the map that is greater
187     * than the given key; or null the given key is greater than any key in the
188     * map.
189     * If the map is empty it returns (null,null).
190     */
191   public Object[] getClosestMatch(Object key){
192     if (root==null)return new Object[]{null,null};
193 
194     Entry lub=getCeilEntry(key);
195 
196     if(lub==null){//greatest key in set is still smaller then parameter "key"
197       return new Object[]{lastEntry().value,null};
198     };
199 
200     int cmp=compare(key,lub.key);
201 
202     if (cmp==0){return new Object[]{lub.value,lub.value};}
203     else {
204       Entry prec=getPrecedingEntry(lub.key);
205       if (prec == null) return new Object[]{null,lub.value};
206       else return new Object[]{prec.value,lub.value};
207     }
208   }
209 
210   /** Returns the value associated to the next key in the map if an exact match
211     * doesn't exist. If there is an exact match, the method will return the
212     * value associated to the given key.
213     * @param key the key for wich the look-up will be done.
214     * @return the value associated to the given key or the next available
215     * value
216     */
217   public Object getNextOf(Object key){
218     if (root==null) return null;
219     Entry lub=getCeilEntry(key);
220     if (lub == null) return null;
221     return lub.value;
222   }
223 
224   /**
225     * Returns the value to which this map maps the specified key.  Returns
226     * <tt>null</tt> if the map contains no mapping for this key.  A return
227     * value of <tt>null</tt> does not <i>necessarily</i> indicate that the
228     * map contains no mapping for the key; it's also possible that the map
229     * explicitly maps the key to <tt>null</tt>.  The <tt>containsKey</tt>
230     * operation may be used to distinguish these two cases.
231     *
232     * @param key key whose associated value is to be returned.
233     * @return the value to which this map maps the specified key, or
234     *        <tt>null</tt> if the map contains no mapping for the key.
235     * @throws    ClassCastException key cannot be compared with the keys
236     *     currently in the map.
237     * @throws NullPointerException key is <tt>null</tt> and this map uses
238     *     natural ordering, or its comparator does not tolerate
239     *     <tt>null</tt> keys.
240     *
241     * @see #containsKey(Object)
242     */
243   public Object get(Object key) {
244     Entry p = getEntry(key);
245     return (p==null ? null : p.value);
246   }
247 
248   /**
249     * Returns the comparator used to order this map, or <tt>null</tt> if this
250     * map uses its keys' natural order.
251     *
252     * @return the comparator associated with this sorted map, or
253     *          <tt>null</tt> if it uses its keys' natural sort method.
254     */
255   public Comparator comparator() {
256       return comparator;
257   }
258 
259   /**
260     * Returns the first (lowest) key currently in this sorted map.
261     *
262     * @return the first (lowest) key currently in this sorted map.
263     * @throws    NoSuchElementException Map is empty.
264     */
265   public Object firstKey() {
266       return key(firstEntry());
267   }
268 
269   /**
270     * Returns the last (highest) key currently in this sorted map.
271     *
272     * @return the last (highest) key currently in this sorted map.
273     * @throws    NoSuchElementException Map is empty.
274     */
275   public Object lastKey() {
276       return key(lastEntry());
277   }
278 
279   /**
280     * Copies all of the mappings from the specified map to this map.  These
281     * mappings replace any mappings that this map had for any of the keys
282     * currently in the specified map.
283     *
284     * @param map Mappings to be stored in this map.
285     * @throws    ClassCastException class of a key or value in the specified
286     *             map prevents it from being stored in this map.
287     *
288     * @throws NullPointerException this map does not permit <tt>null</tt>
289     *            keys and a specified key is <tt>null</tt>.
290     */
291   public void putAll(Map map) {
292       int mapSize = map.size();
293       if (size==0 && mapSize!=0 && map instanceof SortedMap) {
294           Comparator c = ((SortedMap)map).comparator();
295           if (c == comparator || (c != null && c.equals(comparator))) {
296             ++modCount;
297             try {
298                 buildFromSorted(mapSize, map.entrySet().iterator(),
299                                 null, null);
300             } catch (java.io.IOException cannotHappen) {
301             } catch (ClassNotFoundException cannotHappen) {
302             }
303             return;
304           }
305       }
306       super.putAll(map);
307   }
308 
309   /**
310     * Returns this map's entry for the given key, or <tt>null</tt> if the map
311     * does not contain an entry for the key.
312     *
313     * @return this map's entry for the given key, or <tt>null</tt> if the map
314     *          does not contain an entry for the key.
315     * @throws ClassCastException if the key cannot be compared with the keys
316     *     currently in the map.
317     * @throws NullPointerException key is <tt>null</tt> and this map uses
318     *     natural order, or its comparator does not tolerate *
319     *     <tt>null</tt> keys.
320     */
321   private Entry getEntry(Object key) {
322     Entry p = root;
323     while (p != null) {
324         int cmp = compare(key,p.key);
325         if (cmp == 0)
326       return p;
327         else if (cmp < 0)
328       p = p.left;
329         else
330       p = p.right;
331     }
332     return null;
333   }
334 
335 
336   /**
337     * Gets the entry corresponding to the specified key; if no such entry
338     * exists, returns the entry for the least key greater than the specified
339     * key; if no such entry exists (i.e., the greatest key in the Tree is less
340     * than the specified key), returns <tt>null</tt>.
341     */
342   private Entry getCeilEntry(Object key) {
343     Entry p = root;
344     if (p==null)
345         return null;
346 
347     while (true) {
348         int cmp = compare(key, p.key);
349         if (cmp == 0) {
350       return p;
351         } else if (cmp < 0) {
352       if (p.left != null)
353           p = p.left;
354       else
355           return p;
356         } else {
357       if (p.right != null) {
358           p = p.right;
359       } else {
360           Entry parent = p.parent;
361           Entry ch = p;
362           while (parent != null && ch == parent.right) {
363         ch = parent;
364         parent = parent.parent;
365           }
366           return parent;
367       }
368         }
369     }
370   }
371 
372   /**
373     * Returns the entry for the greatest key less than the specified key; if
374     * no such entry exists (i.e., the least key in the Tree is greater than
375     * the specified key), returns <tt>null</tt>.
376     */
377   private Entry getPrecedingEntry(Object key) {
378     Entry p = root;
379     if (p==null)return null;
380 
381     while (true) {
382       int cmp = compare(key, p.key);
383       if (cmp > 0) {
384         if (p.right != null) p = p.right;
385         else return p;
386         }else{
387           if (p.left != null) {
388             p = p.left;
389           } else {
390             Entry parent = p.parent;
391             Entry ch = p;
392             while (parent != null && ch == parent.left) {
393               ch = parent;
394               parent = parent.parent;
395             }
396             return parent;
397           }
398         }
399     }//while true
400   }
401 
402   /**
403     * Returns the key corresonding to the specified Entry.  Throw
404     * NoSuchElementException if the Entry is <tt>null</tt>.
405     */
406   private static Object key(Entry e) {
407       if (e==null)
408           throw new NoSuchElementException();
409       return e.key;
410   }
411 
412   /**
413     * Associates the specified value with the specified key in this map.
414     * If the map previously contained a mapping for this key, the old
415     * value is replaced.
416     *
417     * @param key key with which the specified value is to be associated.
418     * @param value value to be associated with the specified key.
419     *
420     * @return previous value associated with specified key, or <tt>null</tt>
421     *        if there was no mapping for key.  A <tt>null</tt> return can
422     *        also indicate that the map previously associated <tt>null</tt>
423     *        with the specified key.
424     * @throws    ClassCastException key cannot be compared with the keys
425     *     currently in the map.
426     * @throws NullPointerException key is <tt>null</tt> and this map uses
427     *     natural order, or its comparator does not tolerate
428     *     <tt>null</tt> keys.
429     */
430   public Object put(Object key, Object value) {
431     Entry t = root;
432 
433     if (t == null) {
434         incrementSize();
435         root = new Entry(key, value, null);
436         return null;
437     }
438 
439     while (true) {
440         int cmp = compare(key, t.key);
441         if (cmp == 0) {
442       return t.setValue(value);
443         } else if (cmp < 0) {
444       if (t.left != null) {
445           t = t.left;
446       } else {
447           incrementSize();
448           t.left = new Entry(key, value, t);
449           fixAfterInsertion(t.left);
450           return null;
451       }
452         } else { // cmp > 0
453       if (t.right != null) {
454           t = t.right;
455       } else {
456           incrementSize();
457           t.right = new Entry(key, value, t);
458           fixAfterInsertion(t.right);
459           return null;
460       }
461         }
462     }
463   }
464 
465   /**
466     * Removes the mapping for this key from this RBTreeMap if present.
467     *
468     * @return previous value associated with specified key, or <tt>null</tt>
469     *        if there was no mapping for key.  A <tt>null</tt> return can
470     *        also indicate that the map previously associated
471     *        <tt>null</tt> with the specified key.
472     *
473     * @throws    ClassCastException key cannot be compared with the keys
474     *     currently in the map.
475     * @throws NullPointerException key is <tt>null</tt> and this map uses
476     *     natural order, or its comparator does not tolerate
477     *     <tt>null</tt> keys.
478     */
479   public Object remove(Object key) {
480     Entry p = getEntry(key);
481     if (p == null)
482         return null;
483 
484     Object oldValue = p.value;
485     deleteEntry(p);
486     return oldValue;
487   }
488 
489   /**
490     * Removes all mappings from this RBTreeMap.
491     */
492   public void clear() {
493     modCount++;
494     size = 0;
495     root = null;
496   }
497 
498   /**
499     * Returns a shallow copy of this <tt>RBTreeMap</tt> instance. (The keys and
500     * values themselves are not cloned.)
501     *
502     * @return a shallow copy of this Map.
503     */
504   public Object clone() {
505     return new RBTreeMap(this);
506   }
507 
508 
509   // Views
510 
511   /**
512     * These fields are initialized to contain an instance of the appropriate
513     * view the first time this view is requested.  The views are stateless,
514     * so there's no reason to create more than one of each.
515     */
516   private transient Set   keySet = null;
517   private transient Set   entrySet = null;
518   private transient Collection  values = null;
519 
520   /**
521     * Returns a Set view of the keys contained in this map.  The set's
522     * iterator will return the keys in ascending order.  The map is backed by
523     * this <tt>RBTreeMap</tt> instance, so changes to this map are reflected in
524     * the Set, and vice-versa.  The Set supports element removal, which
525     * removes the corresponding mapping from the map, via the
526     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
527     * <tt>retainAll</tt>, and <tt>clear</tt> operations.  It does not support
528     * the <tt>add</tt> or <tt>addAll</tt> operations.
529     *
530     * @return a set view of the keys contained in this RBTreeMap.
531     */
532   public Set keySet() {
533     if (keySet == null) {
534       keySet = new AbstractSet() {
535 
536         public java.util.Iterator iterator() {
537             return new Iterator(KEYS);
538         }
539 
540         public int size() {
541           return RBTreeMap.this.size();
542         }
543 
544         public boolean contains(Object o) {
545           return containsKey(o);
546         }
547 
548         public boolean remove(Object o) {
549           return RBTreeMap.this.remove(o) != null;
550         }
551 
552         public void clear() {
553           RBTreeMap.this.clear();
554         }
555       };
556     }
557     return keySet;
558   }
559 
560   /**
561     * Returns a collection view of the values contained in this map.  The
562     * collection's iterator will return the values in the order that their
563     * corresponding keys appear in the tree.  The collection is backed by
564     * this <tt>RBTreeMap</tt> instance, so changes to this map are reflected in
565     * the collection, and vice-versa.  The collection supports element
566     * removal, which removes the corresponding mapping from the map through
567     * the <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
568     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
569     * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
570     *
571     * @return a collection view of the values contained in this map.
572     */
573   public Collection values() {
574     if (values == null) {
575       values = new AbstractCollection() {
576         public java.util.Iterator iterator() {
577             return new Iterator(VALUES);
578         }
579 
580         public int size() {
581             return RBTreeMap.this.size();
582         }
583 
584         public boolean contains(Object o) {
585             for (Entry e = firstEntry(); e != null; e = successor(e))
586                 if (valEquals(e.getValue(), o))
587                     return true;
588             return false;
589         }
590 
591         public boolean remove(Object o) {
592           for (Entry e = firstEntry(); e != null; e = successor(e)) {
593             if (valEquals(e.getValue(), o)) {
594                 deleteEntry(e);
595                 return true;
596             }
597           }
598           return false;
599         }
600 
601         public void clear() {
602             RBTreeMap.this.clear();
603         }
604       };
605     }
606     return values;
607   }
608 
609   /**
610     * Returns a set view of the mappings contained in this map.  The set's
611     * iterator returns the mappings in ascending key order.  Each element in
612     * the returned set is a <tt>Map.Entry</tt>.  The set is backed by this
613     * map, so changes to this map are reflected in the set, and vice-versa.
614     * The set supports element removal, which removes the corresponding
615     * mapping from the RBTreeMap, through the <tt>Iterator.remove</tt>,
616     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
617     * <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
618     * <tt>addAll</tt> operations.
619     *
620     * @return a set view of the mappings contained in this map.
621     * @see Map.Entry
622     */
623   public Set entrySet() {
624     if (entrySet == null) {
625       entrySet = new AbstractSet() {
626         public java.util.Iterator iterator() {
627           return new Iterator(ENTRIES);
628         }
629 
630         public boolean contains(Object o) {
631           if (!(o instanceof Map.Entry))
632               return false;
633           Map.Entry entry = (Map.Entry)o;
634           Object value = entry.getValue();
635           Entry p = getEntry(entry.getKey());
636           return p != null && valEquals(p.getValue(), value);
637         }
638 
639         public boolean remove(Object o) {
640           if (!(o instanceof Map.Entry))
641               return false;
642           Map.Entry entry = (Map.Entry)o;
643           Object value = entry.getValue();
644           Entry p = getEntry(entry.getKey());
645           if (p != null && valEquals(p.getValue(), value)) {
646               deleteEntry(p);
647               return true;
648           }
649           return false;
650         }
651 
652         public int size() {
653             return RBTreeMap.this.size();
654         }
655 
656         public void clear() {
657             RBTreeMap.this.clear();
658         }
659       };
660     }
661     return entrySet;
662   }
663 
664   /**
665     * Returns a view of the portion of this map whose keys range from
666     * <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive.  (If
667     * <tt>fromKey</tt> and <tt>toKey</tt> are equal, the returned sorted map
668     * is empty.)  The returned sorted map is backed by this map, so changes
669     * in the returned sorted map are reflected in this map, and vice-versa.
670     * The returned sorted map supports all optional map operations.<p>
671     *
672     * The sorted map returned by this method will throw an
673     * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
674     * less than <tt>fromKey</tt> or greater than or equal to
675     * <tt>toKey</tt>.<p>
676     *
677     * Note: this method always returns a <i>half-open range</i> (which
678     * includes its low endpoint but not its high endpoint).  If you need a
679     * <i>closed range</i> (which includes both endpoints), and the key type
680     * allows for calculation of the successor a given key, merely request the
681     * subrange from <tt>lowEndpoint</tt> to <tt>successor(highEndpoint)</tt>.
682     * For example, suppose that <tt>m</tt> is a sorted map whose keys are
683     * strings.  The following idiom obtains a view containing all of the
684     * key-value mappings in <tt>m</tt> whose keys are between <tt>low</tt>
685     * and <tt>high</tt>, inclusive:
686     *       <pre>    SortedMap sub = m.submap(low, high+"\0");</pre>
687     * A similar technique can be used to generate an <i>open range</i> (which
688     * contains neither endpoint).  The following idiom obtains a view
689     * containing all of the key-value mappings in <tt>m</tt> whose keys are
690     * between <tt>low</tt> and <tt>high</tt>, exclusive:
691     *       <pre>    SortedMap sub = m.subMap(low+"\0", high);</pre>
692     *
693     * @param fromKey low endpoint (inclusive) of the subMap.
694     * @param toKey high endpoint (exclusive) of the subMap.
695     *
696     * @return a view of the portion of this map whose keys range from
697     *          <tt>fromKey</tt>, inclusive, to <tt>toKey</tt>, exclusive.
698     *
699     * @throws NullPointerException if <tt>fromKey</tt> or <tt>toKey</tt> is
700     *     <tt>null</tt> and this map uses natural order, or its
701     *     comparator does not tolerate <tt>null</tt> keys.
702     *
703     * @throws IllegalArgumentException if <tt>fromKey</tt> is greater than
704     *            <tt>toKey</tt>.
705     */
706   public SortedMap subMap(Object fromKey, Object toKey) {
707     return new SubMap(fromKey, toKey);
708   }
709 
710   /**
711     * Returns a view of the portion of this map whose keys are strictly less
712     * than <tt>toKey</tt>.  The returned sorted map is backed by this map, so
713     * changes in the returned sorted map are reflected in this map, and
714     * vice-versa.  The returned sorted map supports all optional map
715     * operations.<p>
716     *
717     * The sorted map returned by this method will throw an
718     * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
719     * greater than or equal to <tt>toKey</tt>.<p>
720     *
721     * Note: this method always returns a view that does not contain its
722     * (high) endpoint.  If you need a view that does contain this endpoint,
723     * and the key type allows for calculation of the successor a given key,
724     * merely request a headMap bounded by <tt>successor(highEndpoint)</tt>.
725     * For example, suppose that suppose that <tt>m</tt> is a sorted map whose
726     * keys are strings.  The following idiom obtains a view containing all of
727     * the key-value mappings in <tt>m</tt> whose keys are less than or equal
728     * to <tt>high</tt>:
729     * <pre>
730     *     SortedMap head = m.headMap(high+"\0");
731     * </pre>
732     *
733     * @param toKey high endpoint (exclusive) of the headMap.
734     * @return a view of the portion of this map whose keys are strictly
735     *          less than <tt>toKey</tt>.
736     * @throws NullPointerException if <tt>toKey</tt> is <tt>null</tt> and
737     *     this map uses natural order, or its comparator does * not
738     *     tolerate <tt>null</tt> keys.
739     */
740   public SortedMap headMap(Object toKey) {
741     return new SubMap(toKey, true);
742   }
743 
744   /**
745     * Returns a view of the portion of this map whose keys are greater than
746     * or equal to <tt>fromKey</tt>.  The returned sorted map is backed by
747     * this map, so changes in the returned sorted map are reflected in this
748     * map, and vice-versa.  The returned sorted map supports all optional map
749     * operations.<p>
750     *
751     * The sorted map returned by this method will throw an
752     * <tt>IllegalArgumentException</tt> if the user attempts to insert a key
753     * less than <tt>fromKey</tt>.<p>
754     *
755     * Note: this method always returns a view that contains its (low)
756     * endpoint.  If you need a view that does not contain this endpoint, and
757     * the element type allows for calculation of the successor a given value,
758     * merely request a tailMap bounded by <tt>successor(lowEndpoint)</tt>.
759     * For For example, suppose that suppose that <tt>m</tt> is a sorted map
760     * whose keys are strings.  The following idiom obtains a view containing
761     * all of the key-value mappings in <tt>m</tt> whose keys are strictly
762     * greater than <tt>low</tt>: <pre>
763     *     SortedMap tail = m.tailMap(low+"\0");
764     * </pre>
765     *
766     * @param fromKey low endpoint (inclusive) of the tailMap.
767     * @return a view of the portion of this map whose keys are greater
768     *          than or equal to <tt>fromKey</tt>.
769     * @throws    NullPointerException fromKey is <tt>null</tt> and this
770     *     map uses natural ordering, or its comparator does
771     *            not tolerate <tt>null</tt> keys.
772     */
773   public SortedMap tailMap(Object fromKey) {
774     return new SubMap(fromKey, false);
775   }
776 
777   private class SubMap extends AbstractMap
778          implements SortedMap, java.io.Serializable {
779 
780     // fromKey is significant only if fromStart is false.  Similarly,
781     // toKey is significant only if toStart is false.
782     private boolean fromStart = false, toEnd = false;
783     private Object  fromKey,           toKey;
784 
785     SubMap(Object fromKey, Object toKey) {
786       if (compare(fromKey, toKey) > 0)
787         throw new IllegalArgumentException("fromKey > toKey");
788       this.fromKey = fromKey;
789       this.toKey = toKey;
790     }
791 
792     SubMap(Object key, boolean headMap) {
793       if (headMap) {
794           fromStart = true;
795           toKey = key;
796       } else {
797           toEnd = true;
798           fromKey = key;
799       }
800     }
801 
802     SubMap(boolean fromStart, Object fromKey, boolean toEnd, Object toKey){
803       this.fromStart = fromStart;
804       this.fromKey= fromKey;
805       this.toEnd = toEnd;
806       this.toKey = toKey;
807     }
808 
809     public boolean isEmpty() {
810       return entrySet.isEmpty();
811     }
812 
813     public boolean containsKey(Object key) {
814       return inRange(key) && RBTreeMap.this.containsKey(key);
815     }
816 
817     public Object get(Object key) {
818       if (!inRange(key))
819         return null;
820       return RBTreeMap.this.get(key);
821     }
822 
823     public Object put(Object key, Object value) {
824       if (!inRange(key))
825         throw new IllegalArgumentException("key out of range");
826       return RBTreeMap.this.put(key, value);
827     }
828 
829     public Comparator comparator() {
830         return comparator;
831     }
832 
833     public Object firstKey() {
834         return key(fromStart ? firstEntry() : getCeilEntry(fromKey));
835     }
836 
837     public Object lastKey() {
838         return key(toEnd ? lastEntry() : getPrecedingEntry(toKey));
839     }
840 
841     private transient Set entrySet = new EntrySetView();
842 
843     public Set entrySet() {
844         return entrySet;
845     }
846 
847     private class EntrySetView extends AbstractSet {
848       private transient int size = -1, sizeModCount;
849 
850       public int size() {
851         if (size == -1 || sizeModCount != RBTreeMap.this.modCount) {
852           size = 0;  sizeModCount = RBTreeMap.this.modCount;
853           java.util.Iterator i = iterator();
854           while (i.hasNext()) {
855             size++;
856             i.next();
857           }
858         }
859         return size;
860       } // size
861 
862       public boolean isEmpty() {
863         return !iterator().hasNext();
864       }// isEmpty
865 
866       public boolean contains(Object o) {
867         if (!(o instanceof Map.Entry))
868           return false;
869 
870         Map.Entry entry = (Map.Entry)o;
871         Object key = entry.getKey();
872         if (!inRange(key))
873           return false;
874         RBTreeMap.Entry node = getEntry(key);
875         return node != null &&
876                  valEquals(node.getValue(), entry.getValue());
877       } // contains
878 
879       public boolean remove(Object o) {
880         if (!(o instanceof Map.Entry))
881           return false;
882         Map.Entry entry = (Map.Entry)o;
883         Object key = entry.getKey();
884         if (!inRange(key))
885           return false;
886         RBTreeMap.Entry node = getEntry(key);
887         if (node!=null && valEquals(node.getValue(),entry.getValue())){
888           deleteEntry(node);
889           return true;
890         }
891         return false;
892       }
893 
894       public java.util.Iterator iterator() {
895         return new Iterator(
896                   (fromStart ? firstEntry() : getCeilEntry(fromKey)),
897                   (toEnd     ? null       : getCeilEntry(toKey)));
898       }
899     } // EntrySetView
900 
901     public SortedMap subMap(Object fromKey, Object toKey) {
902       if (!inRange(fromKey))
903         throw new IllegalArgumentException("fromKey out of range");
904       if (!inRange2(toKey))
905         throw new IllegalArgumentException("toKey out of range");
906       return new SubMap(fromKey, toKey);
907     }
908 
909     public SortedMap headMap(Object toKey) {
910       if (!inRange2(toKey))
911         throw new IllegalArgumentException("toKey out of range");
912       return new SubMap(fromStart, fromKey, false, toKey);
913     }
914 
915     public SortedMap tailMap(Object fromKey) {
916       if (!inRange(fromKey))
917         throw new IllegalArgumentException("fromKey out of range");
918       return new SubMap(false, fromKey, toEnd, toKey);
919     }
920 
921     private boolean inRange(Object key) {
922       return (fromStart || compare(key, fromKey) >= 0) &&
923                      (toEnd     || compare(key, toKey)   <  0);
924     }
925 
926     // This form allows the high endpoint (as well as all legit keys)
927     private boolean inRange2(Object key) {
928       return (fromStart || compare(key, fromKey) >= 0) &&
929                  (toEnd     || compare(key, toKey)   <= 0);
930     }
931     static final long serialVersionUID = 4333473260468321526L;
932   } // SubMap
933 
934   // Types of Iterators
935   private static final int KEYS = 0;
936 
937   private static final int VALUES = 1;
938 
939   private static final int ENTRIES = 2;
940 
941   /**
942     * RBTreeMap Iterator.
943     */
944   private class Iterator implements java.util.Iterator {
945     private int type;
946 
947     private int expectedModCount = RBTreeMap.this.modCount;
948 
949     private Entry lastReturned = null;
950 
951     private Entry next;
952 
953     private Entry firstExcluded = null;
954 
955     Iterator(int type) {
956       this.type = type;
957       next = firstEntry();
958     }
959 
960     Iterator(Entry first, Entry firstExcluded) {
961       type = ENTRIES;
962       next = first;
963       this.firstExcluded = firstExcluded;
964     }
965 
966     public boolean hasNext() {
967       return next != firstExcluded;
968     } //hasNext
969 
970     public Object next() {
971       if (next == firstExcluded)
972         throw new NoSuchElementException();
973 
974       if (modCount != expectedModCount)
975         throw new ConcurrentModificationException();
976 
977       lastReturned = next;
978       next = successor(next);
979       return (type == KEYS ? lastReturned.key :
980         (type == VALUES ? lastReturned.value : lastReturned));
981     } // next
982 
983     public void remove() {
984       if (lastReturned == null)
985         throw new IllegalStateException();
986 
987       if (modCount != expectedModCount)
988         throw new ConcurrentModificationException();
989 
990       deleteEntry(lastReturned);
991       expectedModCount++;
992       lastReturned = null;
993     } // remove
994   } //Iterator
995 
996   /**
997     * Compares two keys using the correct comparison method for this RBTreeMap.
998     */
999   private int compare(Object k1, Object k2) {
1000    return (comparator==null ? ((Comparable)k1).compareTo(k2)
1001       : comparator.compare(k1, k2));
1002  }
1003
1004  /**
1005    * Test two values  for equality.  Differs from o1.equals(o2) only in
1006    * that it copes with with <tt>null</tt> o1 properly.
1007    */
1008  private static boolean valEquals(Object o1, Object o2) {
1009    return (o1==null ? o2==null : o1.equals(o2));
1010  }
1011
1012  private static final boolean RED   = false;
1013
1014  private static final boolean BLACK = true;
1015
1016  /**
1017    * Node in the Tree.  Doubles as a means to pass key-value pairs back to
1018    * user (see Map.Entry).
1019    */
1020
1021  static class Entry implements Map.Entry {
1022    Object key;
1023    Object value;
1024    Entry left = null;
1025    Entry right = null;
1026    Entry parent;
1027    boolean color = BLACK;
1028
1029    /** Make a new cell with given key, value, and parent, and with
1030      * <tt>null</tt> child links, and BLACK color.
1031      */
1032    Entry(Object key, Object value, Entry parent) {
1033      this.key = key;
1034      this.value = value;
1035      this.parent = parent;
1036    }
1037
1038    /**
1039      * Returns the key.
1040      *
1041      * @return the key.
1042      */
1043    public Object getKey() {
1044        return key;
1045    }
1046
1047    /**
1048      * Returns the value associated with the key.
1049      *
1050      * @return the value associated with the key.
1051      */
1052    public Object getValue() {
1053        return value;
1054    }
1055
1056    /**
1057      * Replaces the value currently associated with the key with the given
1058      * value.
1059      *
1060      * @return the value associated with the key before this method was
1061      * called.
1062      */
1063    public Object setValue(Object value) {
1064        Object oldValue = this.value;
1065        this.value = value;
1066        return oldValue;
1067    }
1068
1069    public boolean equals(Object o) {
1070        if (!(o instanceof Map.Entry))
1071      return false;
1072        Map.Entry e = (Map.Entry)o;
1073
1074        return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
1075    } // equals
1076
1077    public int hashCode() {
1078        int keyHash = (key==null ? 0 : key.hashCode());
1079        int valueHash = (value==null ? 0 : value.hashCode());
1080        return keyHash ^ valueHash;
1081    } // hashCode
1082
1083    public String toString() {
1084        return key + "=" + value;
1085    }
1086  } // Entry
1087
1088  /**
1089    * Returns the first Entry in the RBTreeMap (according to the RBTreeMap's
1090    * key-sort function).  Returns null if the RBTreeMap is empty.
1091    */
1092  private Entry firstEntry() {
1093    Entry p = root;
1094    if (p != null)
1095      while (p.left != null)
1096        p = p.left;
1097    return p;
1098  }
1099
1100  /**
1101    * Returns the last Entry in the RBTreeMap (according to the RBTreeMap's
1102    * key-sort function).  Returns null if the RBTreeMap is empty.
1103    */
1104  private Entry lastEntry() {
1105    Entry p = root;
1106    if (p != null)
1107      while (p.right != null)
1108        p = p.right;
1109    return p;
1110  }
1111
1112  /**
1113    * Returns the successor of the specified Entry, or null if no such.
1114    */
1115  private Entry successor(Entry t) {
1116    if (t == null)
1117      return null;
1118    else if (t.right != null) {
1119      Entry p = t.right;
1120      while (p.left != null)
1121        p = p.left;
1122      return p;
1123    } else {
1124      Entry p = t.parent;
1125      Entry ch = t;
1126      while (p != null && ch == p.right) {
1127        ch = p;
1128        p = p.parent;
1129      }
1130      return p;
1131    }
1132  } // successor
1133
1134  /**
1135    * Balancing operations.
1136    *
1137    * Implementations of rebalancings during insertion and deletion are
1138    * slightly different than the CLR version.  Rather than using dummy
1139    * nilnodes, we use a set of accessors that deal properly with null.  They
1140    * are used to avoid messiness surrounding nullness checks in the main
1141    * algorithms.
1142    */
1143
1144  private static boolean colorOf(Entry p) {
1145    return (p == null ? BLACK : p.color);
1146  }
1147
1148  private static Entry  parentOf(Entry p) {
1149    return (p == null ? null: p.parent);
1150  }
1151
1152  private static void setColor(Entry p, boolean c) {
1153    if (p != null)  p.color = c;
1154  }
1155
1156  private static Entry  leftOf(Entry p) {
1157    return (p == null)? null: p.left;
1158  }
1159
1160  private static Entry  rightOf(Entry p) {
1161    return (p == null)? null: p.right;
1162  }
1163
1164  /** From CLR **/
1165  private void rotateLeft(Entry p) {
1166    Entry r = p.right;
1167    p.right = r.left;
1168
1169    if (r.left != null)
1170      r.left.parent = p;
1171    r.parent = p.parent;
1172
1173    if (p.parent == null)
1174      root = r;
1175    else if (p.parent.left == p)
1176      p.parent.left = r;
1177    else
1178      p.parent.right = r;
1179    r.left = p;
1180    p.parent = r;
1181  }
1182
1183  /** From CLR **/
1184  private void rotateRight(Entry p) {
1185    Entry l = p.left;
1186    p.left = l.right;
1187
1188    if (l.right != null) l.right.parent = p;
1189    l.parent = p.parent;
1190
1191    if (p.parent == null)
1192        root = l;
1193    else if (p.parent.right == p)
1194        p.parent.right = l;
1195    else p.parent.left = l;
1196
1197    l.right = p;
1198    p.parent = l;
1199  }
1200
1201
1202  /** From CLR **/
1203  private void fixAfterInsertion(Entry x) {
1204    x.color = RED;
1205
1206    while (x != null && x != root && x.parent.color == RED) {
1207      if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
1208        Entry y = rightOf(parentOf(parentOf(x)));
1209        if (colorOf(y) == RED) {
1210          setColor(parentOf(x), BLACK);
1211          setColor(y, BLACK);
1212          setColor(parentOf(parentOf(x)), RED);
1213          x = parentOf(parentOf(x));
1214        } else {
1215          if (x == rightOf(parentOf(x))) {
1216            x = parentOf(x);
1217            rotateLeft(x);
1218          }
1219          setColor(parentOf(x), BLACK);
1220          setColor(parentOf(parentOf(x)), RED);
1221          if (parentOf(parentOf(x)) != null)
1222            rotateRight(parentOf(parentOf(x)));
1223        }
1224      } else {
1225        Entry y = leftOf(parentOf(parentOf(x)));
1226        if (colorOf(y) == RED) {
1227            setColor(parentOf(x), BLACK);
1228            setColor(y, BLACK);
1229            setColor(parentOf(parentOf(x)), RED);
1230            x = parentOf(parentOf(x));
1231        } else {
1232          if (x == leftOf(parentOf(x))) {
1233            x = parentOf(x);
1234            rotateRight(x);
1235          }
1236          setColor(parentOf(x),  BLACK);
1237          setColor(parentOf(parentOf(x)), RED);
1238          if (parentOf(parentOf(x)) != null)
1239            rotateLeft(parentOf(parentOf(x)));
1240        }
1241      }
1242    }
1243    root.color = BLACK;
1244  } // fixAfterInsertion
1245
1246  /**
1247    * Delete node p, and then rebalance the tree.
1248    */
1249  private void deleteEntry(Entry p) {
1250    decrementSize();
1251
1252    // If strictly internal, first swap position with successor.
1253    if (p.left != null && p.right != null) {
1254        Entry s = successor(p);
1255        swapPosition(s, p);
1256    }
1257
1258    // Start fixup at replacement node, if it exists.
1259    Entry replacement = (p.left != null ? p.left : p.right);
1260
1261    if (replacement != null) {
1262      // Link replacement to parent
1263      replacement.parent = p.parent;
1264      if (p.parent == null)
1265        root = replacement;
1266      else if (p == p.parent.left)
1267        p.parent.left  = replacement;
1268      else
1269        p.parent.right = replacement;
1270
1271    // Null out links so they are OK to use by fixAfterDeletion.
1272    p.left = p.right = p.parent = null;
1273
1274    // Fix replacement
1275    if (p.color == BLACK)
1276      fixAfterDeletion(replacement);
1277    } else if (p.parent == null) { // return if we are the only node.
1278      root = null;
1279    } else { //  No children. Use self as phantom replacement and unlink.
1280      if (p.color == BLACK)
1281        fixAfterDeletion(p);
1282
1283      if (p.parent != null) {
1284        if (p == p.parent.left)
1285          p.parent.left = null;
1286        else if (p == p.parent.right)
1287          p.parent.right = null;
1288        p.parent = null;
1289      }
1290    }
1291  } // deleteEntry
1292
1293  /** From CLR **/
1294  private void fixAfterDeletion(Entry x) {
1295    while (x != root && colorOf(x) == BLACK) {
1296      if (x == leftOf(parentOf(x))) {
1297        Entry sib = rightOf(parentOf(x));
1298
1299        if (colorOf(sib) == RED) {
1300          setColor(sib, BLACK);
1301          setColor(parentOf(x), RED);
1302          rotateLeft(parentOf(x));
1303          sib = rightOf(parentOf(x));
1304        }
1305
1306        if (colorOf(leftOf(sib))  == BLACK &&
1307            colorOf(rightOf(sib)) == BLACK) {
1308          setColor(sib,  RED);
1309          x = parentOf(x);
1310        } else {
1311          if (colorOf(rightOf(sib)) == BLACK) {
1312            setColor(leftOf(sib), BLACK);
1313            setColor(sib, RED);
1314            rotateRight(sib);
1315            sib = rightOf(parentOf(x));
1316          }
1317          setColor(sib, colorOf(parentOf(x)));
1318          setColor(parentOf(x), BLACK);
1319          setColor(rightOf(sib), BLACK);
1320          rotateLeft(parentOf(x));
1321          x = root;
1322        }
1323      } else { // symmetric
1324        Entry sib = leftOf(parentOf(x));
1325
1326        if (colorOf(sib) == RED) {
1327          setColor(sib, BLACK);
1328          setColor(parentOf(x), RED);
1329          rotateRight(parentOf(x));
1330          sib = leftOf(parentOf(x));
1331        }
1332
1333        if (colorOf(rightOf(sib)) == BLACK &&
1334          colorOf(leftOf(sib)) == BLACK) {
1335          setColor(sib,  RED);
1336          x = parentOf(x);
1337        } else {
1338          if (colorOf(leftOf(sib)) == BLACK) {
1339            setColor(rightOf(sib), BLACK);
1340            setColor(sib, RED);
1341            rotateLeft(sib);
1342            sib = leftOf(parentOf(x));
1343          }
1344          setColor(sib, colorOf(parentOf(x)));
1345          setColor(parentOf(x), BLACK);
1346          setColor(leftOf(sib), BLACK);
1347          rotateRight(parentOf(x));
1348          x = root;
1349        }
1350      }
1351    }
1352    setColor(x, BLACK);
1353  } // fixAfterDeletion
1354
1355  /**
1356    * Swap the linkages of two nodes in a tree.
1357    */
1358  private void swapPosition(Entry x, Entry y) {
1359    // Save initial values.
1360    Entry px = x.parent, lx = x.left, rx = x.right;
1361    Entry py = y.parent, ly = y.left, ry = y.right;
1362    boolean xWasLeftChild = px != null && x == px.left;
1363    boolean yWasLeftChild = py != null && y == py.left;
1364
1365    // Swap, handling special cases of one being the other's parent.
1366    if (x == py) {  // x was y's parent
1367      x.parent = y;
1368
1369      if (yWasLeftChild) {
1370        y.left = x;
1371        y.right = rx;
1372      } else {
1373        y.right = x;
1374        y.left = lx;
1375      }
1376    } else {
1377      x.parent = py;
1378
1379      if (py != null) {
1380        if (yWasLeftChild)
1381          py.left = x;
1382        else
1383          py.right = x;
1384      }
1385      y.left = lx;
1386      y.right = rx;
1387    }
1388
1389    if (y == px) { // y was x's parent
1390      y.parent = x;
1391      if (xWasLeftChild) {
1392        x.left = y;
1393        x.right = ry;
1394      } else {
1395        x.right = y;
1396        x.left = ly;
1397      }
1398    } else {
1399      y.parent = px;
1400      if (px != null) {
1401        if (xWasLeftChild)
1402          px.left = y;
1403        else
1404          px.right = y;
1405      }
1406      x.left = ly;
1407      x.right = ry;
1408    }
1409
1410    // Fix children's parent pointers
1411    if (x.left != null)
1412      x.left.parent = x;
1413
1414    if (x.right != null)
1415      x.right.parent = x;
1416
1417    if (y.left != null)
1418      y.left.parent = y;
1419
1420    if (y.right != null)
1421      y.right.parent = y;
1422
1423    // Swap colors
1424    boolean c = x.color;
1425    x.color = y.color;
1426    y.color = c;
1427
1428    // Check if root changed
1429    if (root == x)
1430        root = y;
1431    else if (root == y)
1432        root = x;
1433  } // swapPosition
1434
1435
1436
1437
1438  /**
1439    * Save the state of the <tt>RBTreeMap</tt> instance to a stream (i.e.,
1440    * serialize it).
1441    *
1442    * @serialData The <i>size</i> of the RBTreeMap (the number of key-value
1443    *      mappings) is emitted (int), followed by the key (Object)
1444    *      and value (Object) for each key-value mapping represented
1445    *      by the RBTreeMap. The key-value mappings are emitted in
1446    *      key-order (as determined by the RBTreeMap's Comparator,
1447    *      or by the keys' natural ordering if the RBTreeMap has no
1448    *             Comparator).
1449    */
1450  private void writeObject(java.io.ObjectOutputStream s)
1451      throws java.io.IOException {
1452
1453    // Write out the Comparator and any hidden stuff
1454    s.defaultWriteObject();
1455
1456    // Write out size (number of Mappings)
1457    s.writeInt(size);
1458
1459          // Write out keys and values (alternating)
1460    for (java.util.Iterator i = entrySet().iterator(); i.hasNext(); ) {
1461              Entry e = (Entry)i.next();
1462              s.writeObject(e.key);
1463              s.writeObject(e.value);
1464    }
1465  } // writeObject
1466
1467
1468
1469  /**
1470    * Reconstitute the <tt>RBTreeMap</tt> instance from a stream (i.e.,
1471    * deserialize it).
1472    */
1473  private void readObject(final java.io.ObjectInputStream s)
1474      throws java.io.IOException, ClassNotFoundException {
1475
1476    // Read in the Comparator and any hidden stuff
1477    s.defaultReadObject();
1478
1479    // Read in size
1480    int size = s.readInt();
1481
1482    buildFromSorted(size, null, s, null);
1483  } // readObject
1484
1485  /** Intended to be called only from TreeSet.readObject */
1486  void readTreeSet(int size, java.io.ObjectInputStream s, Object defaultVal)
1487      throws java.io.IOException, ClassNotFoundException {
1488    buildFromSorted(size, null, s, defaultVal);
1489  }
1490
1491  /** Intended to be called only from TreeSet.addAll */
1492  void addAllForTreeSet(SortedSet set, Object defaultVal) {
1493    try {
1494      buildFromSorted(set.size(), set.iterator(), null, defaultVal);
1495    } catch (java.io.IOException cannotHappen) {
1496    } catch (ClassNotFoundException cannotHappen) {
1497    }
1498  }
1499
1500
1501  /**
1502    * Linear time tree building algorithm from sorted data.  Can accept keys
1503    * and/or values from iterator or stream. This leads to too many
1504    * parameters, but seems better than alternatives.  The four formats
1505    * that this method accepts are:
1506    *
1507    *   1) An iterator of Map.Entries.  (it != null, defaultVal == null).
1508    *    2) An iterator of keys.         (it != null, defaultVal != null).
1509    *   3) A stream of alternating serialized keys and values.
1510    *           (it == null, defaultVal == null).
1511    *   4) A stream of serialized keys. (it == null, defaultVal != null).
1512    *
1513    * It is assumed that the comparator of the RBTreeMap is already set prior
1514    * to calling this method.
1515    *
1516    * @param size the number of keys (or key-value pairs) to be read from
1517    *       the iterator or stream.
1518    * @param it If non-null, new entries are created from entries
1519    *        or keys read from this iterator.
1520    * @param str If non-null, new entries are created from keys and
1521    *       possibly values read from this stream in serialized form.
1522    *        Exactly one of it and str should be non-null.
1523    * @param defaultVal if non-null, this default value is used for
1524    *        each value in the map.  If null, each value is read from
1525    *        iterator or stream, as described above.
1526    * @throws IOException propagated from stream reads. This cannot
1527    *         occur if str is null.
1528    * @throws ClassNotFoundException propagated from readObject.
1529    *         This cannot occur if str is null.
1530    */
1531  private void buildFromSorted(int size, java.util.Iterator it,
1532                                java.io.ObjectInputStream str,
1533                                Object defaultVal)
1534    throws  java.io.IOException, ClassNotFoundException {
1535
1536    this.size = size;
1537    root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
1538                             it, str, defaultVal);
1539  } // buildFromSorted
1540
1541  /**
1542    * Recursive "helper method" that does the real work of the
1543    * of the previous method.  Identically named parameters have
1544    * identical definitions.  Additional parameters are documented below.
1545    * It is assumed that the comparator and size fields of the RBTreeMap are
1546    * already set prior to calling this method.  (It ignores both fields.)
1547    *
1548    * @param level the current level of tree. Initial call should be 0.
1549    * @param lo the first element index of this subtree. Initial should be 0.
1550    * @param hi the last element index of this subtree.  Initial should be
1551    *       size-1.
1552    * @param redLevel the level at which nodes should be red.
1553    *        Must be equal to computeRedLevel for tree of this size.
1554    */
1555  private static Entry buildFromSorted(int level, int lo, int hi,
1556                                       int redLevel,
1557                                       java.util.Iterator it,
1558                                       java.io.ObjectInputStream str,
1559                                       Object defaultVal)
1560    throws  java.io.IOException, ClassNotFoundException {
1561    /*
1562     * Strategy: The root is the middlemost element. To get to it, we
1563     * have to first recursively construct the entire left subtree,
1564     * so as to grab all of its elements. We can then proceed with right
1565     * subtree.
1566     *
1567     * The lo and hi arguments are the minimum and maximum
1568     * indices to pull out of the iterator or stream for current subtree.
1569     * They are not actually indexed, we just proceed sequentially,
1570     * ensuring that items are extracted in corresponding order.
1571     */
1572
1573    if (hi < lo) return null;
1574
1575    int mid = (lo + hi) / 2;
1576
1577    Entry left  = null;
1578    if (lo < mid)
1579      left = buildFromSorted(level+1, lo, mid - 1, redLevel,
1580                               it, str, defaultVal);
1581
1582    // extract key and/or value from iterator or stream
1583    Object key;
1584    Object value;
1585
1586    if (it != null) { // use iterator
1587
1588      if (defaultVal==null) {
1589        Map.Entry entry = (Map.Entry) it.next();
1590        key = entry.getKey();
1591        value = entry.getValue();
1592      } else {
1593        key = it.next();
1594        value = defaultVal;
1595      }
1596    } else { // use stream
1597      key = str.readObject();
1598      value = (defaultVal != null ? defaultVal : str.readObject());
1599    }
1600
1601    Entry middle =  new Entry(key, value, null);
1602
1603    // color nodes in non-full bottommost level red
1604    if (level == redLevel)
1605      middle.color = RED;
1606
1607    if (left != null) {
1608      middle.left = left;
1609      left.parent = middle;
1610    }
1611
1612    if (mid < hi) {
1613      Entry right = buildFromSorted(level+1, mid+1, hi, redLevel,
1614                                    it, str, defaultVal);
1615      middle.right = right;
1616      right.parent = middle;
1617    }
1618
1619    return middle;
1620
1621  } // Entry buildFromSorted
1622
1623  /**
1624    * Find the level down to which to assign all nodes BLACK.  This is the
1625    * last `full' level of the complete binary tree produced by
1626    * buildTree. The remaining nodes are colored RED. (This makes a `nice'
1627    * set of color assignments wrt future insertions.) This level number is
1628    * computed by finding the number of splits needed to reach the zeroeth
1629    * node.  (The answer is ~lg(N), but in any case must be computed by same
1630    * quick O(lg(N)) loop.)
1631    */
1632  private static int computeRedLevel(int sz) {
1633    int level = 0;
1634    for (int m = sz - 1; m >= 0; m = m / 2 - 1)
1635        level++;
1636    return level;
1637  }
1638
1639} // class RBTreeMap
1640