ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeSetTest.java
Revision: 1.28
Committed: Tue Apr 2 22:18:26 2013 UTC (11 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.27: +11 -0 lines
Log Message:
add new test testAllAll_idempotent

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.20 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6    
7     import junit.framework.*;
8 jsr166 1.23 import java.util.Arrays;
9     import java.util.BitSet;
10     import java.util.Collection;
11     import java.util.Comparator;
12     import java.util.Iterator;
13     import java.util.NavigableSet;
14     import java.util.NoSuchElementException;
15     import java.util.Random;
16     import java.util.Set;
17     import java.util.SortedSet;
18     import java.util.TreeSet;
19 dl 1.1
20     public class TreeSetTest extends JSR166TestCase {
21     public static void main(String[] args) {
22 jsr166 1.13 junit.textui.TestRunner.run(suite());
23 dl 1.1 }
24     public static Test suite() {
25 jsr166 1.7 return new TestSuite(TreeSetTest.class);
26 dl 1.1 }
27    
28 jsr166 1.4 static class MyReverseComparator implements Comparator {
29 dl 1.1 public int compare(Object x, Object y) {
30 jsr166 1.11 return ((Comparable)y).compareTo(x);
31 dl 1.1 }
32     }
33    
34     /**
35     * The number of elements to place in collections, arrays, etc.
36     */
37     static final int SIZE = 20;
38    
39     /**
40 jsr166 1.27 * Returns a new set of given size containing consecutive
41 dl 1.1 * Integers 0 ... n.
42     */
43 jsr166 1.18 private TreeSet<Integer> populatedSet(int n) {
44     TreeSet<Integer> q = new TreeSet<Integer>();
45 dl 1.1 assertTrue(q.isEmpty());
46 jsr166 1.7 for (int i = n-1; i >= 0; i-=2)
47     assertTrue(q.add(new Integer(i)));
48     for (int i = (n & 1); i < n; i+=2)
49     assertTrue(q.add(new Integer(i)));
50 dl 1.1 assertFalse(q.isEmpty());
51 jsr166 1.7 assertEquals(n, q.size());
52 dl 1.1 return q;
53     }
54    
55     /**
56 jsr166 1.27 * Returns a new set of first 5 ints.
57 dl 1.1 */
58     private TreeSet set5() {
59     TreeSet q = new TreeSet();
60     assertTrue(q.isEmpty());
61     q.add(one);
62     q.add(two);
63     q.add(three);
64     q.add(four);
65     q.add(five);
66 jsr166 1.7 assertEquals(5, q.size());
67 dl 1.1 return q;
68     }
69 jsr166 1.4
70 dl 1.1 /**
71     * A new set has unbounded capacity
72     */
73     public void testConstructor1() {
74     assertEquals(0, new TreeSet().size());
75     }
76    
77     /**
78     * Initializing from null Collection throws NPE
79     */
80     public void testConstructor3() {
81     try {
82     TreeSet q = new TreeSet((Collection)null);
83     shouldThrow();
84 jsr166 1.8 } catch (NullPointerException success) {}
85 dl 1.1 }
86    
87     /**
88     * Initializing from Collection of null elements throws NPE
89     */
90     public void testConstructor4() {
91     try {
92     Integer[] ints = new Integer[SIZE];
93     TreeSet q = new TreeSet(Arrays.asList(ints));
94     shouldThrow();
95 jsr166 1.8 } catch (NullPointerException success) {}
96 dl 1.1 }
97    
98     /**
99     * Initializing from Collection with some null elements throws NPE
100     */
101     public void testConstructor5() {
102     try {
103     Integer[] ints = new Integer[SIZE];
104     for (int i = 0; i < SIZE-1; ++i)
105     ints[i] = new Integer(i);
106     TreeSet q = new TreeSet(Arrays.asList(ints));
107     shouldThrow();
108 jsr166 1.8 } catch (NullPointerException success) {}
109 dl 1.1 }
110    
111     /**
112     * Set contains all elements of collection used to initialize
113     */
114     public void testConstructor6() {
115 jsr166 1.9 Integer[] ints = new Integer[SIZE];
116     for (int i = 0; i < SIZE; ++i)
117     ints[i] = new Integer(i);
118     TreeSet q = new TreeSet(Arrays.asList(ints));
119     for (int i = 0; i < SIZE; ++i)
120     assertEquals(ints[i], q.pollFirst());
121 dl 1.1 }
122    
123     /**
124     * The comparator used in constructor is used
125     */
126     public void testConstructor7() {
127 jsr166 1.9 MyReverseComparator cmp = new MyReverseComparator();
128     TreeSet q = new TreeSet(cmp);
129     assertEquals(cmp, q.comparator());
130     Integer[] ints = new Integer[SIZE];
131     for (int i = 0; i < SIZE; ++i)
132     ints[i] = new Integer(i);
133     q.addAll(Arrays.asList(ints));
134     for (int i = SIZE-1; i >= 0; --i)
135     assertEquals(ints[i], q.pollFirst());
136 dl 1.1 }
137    
138     /**
139     * isEmpty is true before add, false after
140     */
141     public void testEmpty() {
142     TreeSet q = new TreeSet();
143     assertTrue(q.isEmpty());
144     q.add(new Integer(1));
145     assertFalse(q.isEmpty());
146     q.add(new Integer(2));
147     q.pollFirst();
148     q.pollFirst();
149     assertTrue(q.isEmpty());
150     }
151    
152     /**
153     * size changes when elements added and removed
154     */
155     public void testSize() {
156     TreeSet q = populatedSet(SIZE);
157     for (int i = 0; i < SIZE; ++i) {
158     assertEquals(SIZE-i, q.size());
159     q.pollFirst();
160     }
161     for (int i = 0; i < SIZE; ++i) {
162     assertEquals(i, q.size());
163     q.add(new Integer(i));
164     }
165     }
166    
167     /**
168     * add(null) throws NPE if nonempty
169     */
170     public void testAddNull() {
171 jsr166 1.7 try {
172 dl 1.1 TreeSet q = populatedSet(SIZE);
173     q.add(null);
174     shouldThrow();
175 jsr166 1.8 } catch (NullPointerException success) {}
176 dl 1.1 }
177    
178     /**
179     * Add of comparable element succeeds
180     */
181     public void testAdd() {
182     TreeSet q = new TreeSet();
183     assertTrue(q.add(zero));
184     assertTrue(q.add(one));
185     }
186    
187     /**
188     * Add of duplicate element fails
189     */
190     public void testAddDup() {
191     TreeSet q = new TreeSet();
192     assertTrue(q.add(zero));
193     assertFalse(q.add(zero));
194     }
195    
196     /**
197     * Add of non-Comparable throws CCE
198     */
199     public void testAddNonComparable() {
200     try {
201     TreeSet q = new TreeSet();
202     q.add(new Object());
203     q.add(new Object());
204     q.add(new Object());
205     shouldThrow();
206 jsr166 1.8 } catch (ClassCastException success) {}
207 dl 1.1 }
208    
209     /**
210     * addAll(null) throws NPE
211     */
212     public void testAddAll1() {
213     try {
214     TreeSet q = new TreeSet();
215     q.addAll(null);
216     shouldThrow();
217 jsr166 1.8 } catch (NullPointerException success) {}
218 dl 1.1 }
219 jsr166 1.14
220 dl 1.1 /**
221     * addAll of a collection with null elements throws NPE
222     */
223     public void testAddAll2() {
224     try {
225     TreeSet q = new TreeSet();
226     Integer[] ints = new Integer[SIZE];
227     q.addAll(Arrays.asList(ints));
228     shouldThrow();
229 jsr166 1.8 } catch (NullPointerException success) {}
230 dl 1.1 }
231 jsr166 1.14
232 dl 1.1 /**
233     * addAll of a collection with any null elements throws NPE after
234     * possibly adding some elements
235     */
236     public void testAddAll3() {
237     try {
238     TreeSet q = new TreeSet();
239     Integer[] ints = new Integer[SIZE];
240     for (int i = 0; i < SIZE-1; ++i)
241     ints[i] = new Integer(i);
242     q.addAll(Arrays.asList(ints));
243     shouldThrow();
244 jsr166 1.8 } catch (NullPointerException success) {}
245 dl 1.1 }
246    
247     /**
248     * Set contains all elements of successful addAll
249     */
250     public void testAddAll5() {
251 jsr166 1.9 Integer[] empty = new Integer[0];
252     Integer[] ints = new Integer[SIZE];
253     for (int i = 0; i < SIZE; ++i)
254     ints[i] = new Integer(SIZE-1-i);
255     TreeSet q = new TreeSet();
256     assertFalse(q.addAll(Arrays.asList(empty)));
257     assertTrue(q.addAll(Arrays.asList(ints)));
258     for (int i = 0; i < SIZE; ++i)
259     assertEquals(new Integer(i), q.pollFirst());
260 dl 1.1 }
261    
262     /**
263     * pollFirst succeeds unless empty
264     */
265     public void testPollFirst() {
266     TreeSet q = populatedSet(SIZE);
267     for (int i = 0; i < SIZE; ++i) {
268 jsr166 1.11 assertEquals(i, q.pollFirst());
269 dl 1.1 }
270 jsr166 1.7 assertNull(q.pollFirst());
271 dl 1.1 }
272    
273     /**
274     * pollLast succeeds unless empty
275     */
276     public void testPollLast() {
277     TreeSet q = populatedSet(SIZE);
278     for (int i = SIZE-1; i >= 0; --i) {
279 jsr166 1.11 assertEquals(i, q.pollLast());
280 dl 1.1 }
281 jsr166 1.7 assertNull(q.pollFirst());
282 dl 1.1 }
283    
284     /**
285     * remove(x) removes x and returns true if present
286     */
287     public void testRemoveElement() {
288     TreeSet q = populatedSet(SIZE);
289     for (int i = 1; i < SIZE; i+=2) {
290 jsr166 1.19 assertTrue(q.contains(i));
291     assertTrue(q.remove(i));
292     assertFalse(q.contains(i));
293     assertTrue(q.contains(i-1));
294 dl 1.1 }
295     for (int i = 0; i < SIZE; i+=2) {
296 jsr166 1.19 assertTrue(q.contains(i));
297     assertTrue(q.remove(i));
298     assertFalse(q.contains(i));
299     assertFalse(q.remove(i+1));
300     assertFalse(q.contains(i+1));
301 dl 1.1 }
302     assertTrue(q.isEmpty());
303     }
304 jsr166 1.4
305 dl 1.1 /**
306     * contains(x) reports true when elements added but not yet removed
307     */
308     public void testContains() {
309     TreeSet q = populatedSet(SIZE);
310     for (int i = 0; i < SIZE; ++i) {
311     assertTrue(q.contains(new Integer(i)));
312     q.pollFirst();
313     assertFalse(q.contains(new Integer(i)));
314     }
315     }
316    
317     /**
318     * clear removes all elements
319     */
320     public void testClear() {
321     TreeSet q = populatedSet(SIZE);
322     q.clear();
323     assertTrue(q.isEmpty());
324     assertEquals(0, q.size());
325     q.add(new Integer(1));
326     assertFalse(q.isEmpty());
327     q.clear();
328     assertTrue(q.isEmpty());
329     }
330    
331     /**
332     * containsAll(c) is true when c contains a subset of elements
333     */
334     public void testContainsAll() {
335     TreeSet q = populatedSet(SIZE);
336     TreeSet p = new TreeSet();
337     for (int i = 0; i < SIZE; ++i) {
338     assertTrue(q.containsAll(p));
339     assertFalse(p.containsAll(q));
340     p.add(new Integer(i));
341     }
342     assertTrue(p.containsAll(q));
343     }
344    
345     /**
346     * retainAll(c) retains only those elements of c and reports true if changed
347     */
348     public void testRetainAll() {
349     TreeSet q = populatedSet(SIZE);
350     TreeSet p = populatedSet(SIZE);
351     for (int i = 0; i < SIZE; ++i) {
352     boolean changed = q.retainAll(p);
353     if (i == 0)
354     assertFalse(changed);
355     else
356     assertTrue(changed);
357    
358     assertTrue(q.containsAll(p));
359     assertEquals(SIZE-i, q.size());
360     p.pollFirst();
361     }
362     }
363    
364     /**
365     * removeAll(c) removes only those elements of c and reports true if changed
366     */
367     public void testRemoveAll() {
368     for (int i = 1; i < SIZE; ++i) {
369     TreeSet q = populatedSet(SIZE);
370     TreeSet p = populatedSet(i);
371     assertTrue(q.removeAll(p));
372     assertEquals(SIZE-i, q.size());
373     for (int j = 0; j < i; ++j) {
374     Integer I = (Integer)(p.pollFirst());
375     assertFalse(q.contains(I));
376     }
377     }
378     }
379    
380     /**
381     * lower returns preceding element
382     */
383     public void testLower() {
384     TreeSet q = set5();
385     Object e1 = q.lower(three);
386     assertEquals(two, e1);
387    
388     Object e2 = q.lower(six);
389     assertEquals(five, e2);
390    
391     Object e3 = q.lower(one);
392     assertNull(e3);
393    
394     Object e4 = q.lower(zero);
395     assertNull(e4);
396     }
397    
398     /**
399     * higher returns next element
400     */
401     public void testHigher() {
402     TreeSet q = set5();
403     Object e1 = q.higher(three);
404     assertEquals(four, e1);
405    
406     Object e2 = q.higher(zero);
407     assertEquals(one, e2);
408    
409     Object e3 = q.higher(five);
410     assertNull(e3);
411    
412     Object e4 = q.higher(six);
413     assertNull(e4);
414     }
415    
416     /**
417     * floor returns preceding element
418     */
419     public void testFloor() {
420     TreeSet q = set5();
421     Object e1 = q.floor(three);
422     assertEquals(three, e1);
423    
424     Object e2 = q.floor(six);
425     assertEquals(five, e2);
426    
427     Object e3 = q.floor(one);
428     assertEquals(one, e3);
429    
430     Object e4 = q.floor(zero);
431     assertNull(e4);
432     }
433    
434     /**
435     * ceiling returns next element
436     */
437     public void testCeiling() {
438     TreeSet q = set5();
439     Object e1 = q.ceiling(three);
440     assertEquals(three, e1);
441    
442     Object e2 = q.ceiling(zero);
443     assertEquals(one, e2);
444    
445     Object e3 = q.ceiling(five);
446     assertEquals(five, e3);
447    
448     Object e4 = q.ceiling(six);
449     assertNull(e4);
450     }
451    
452     /**
453 jsr166 1.17 * toArray contains all elements in sorted order
454 dl 1.1 */
455     public void testToArray() {
456     TreeSet q = populatedSet(SIZE);
457 jsr166 1.7 Object[] o = q.toArray();
458     for (int i = 0; i < o.length; i++)
459 jsr166 1.17 assertSame(o[i], q.pollFirst());
460 dl 1.1 }
461    
462     /**
463 jsr166 1.17 * toArray(a) contains all elements in sorted order
464 dl 1.1 */
465     public void testToArray2() {
466 jsr166 1.18 TreeSet<Integer> q = populatedSet(SIZE);
467 jsr166 1.7 Integer[] ints = new Integer[SIZE];
468 jsr166 1.18 Integer[] array = q.toArray(ints);
469     assertSame(ints, array);
470 jsr166 1.5 for (int i = 0; i < ints.length; i++)
471 jsr166 1.17 assertSame(ints[i], q.pollFirst());
472 dl 1.1 }
473 jsr166 1.4
474 dl 1.1 /**
475     * iterator iterates through all elements
476     */
477     public void testIterator() {
478     TreeSet q = populatedSet(SIZE);
479     int i = 0;
480 jsr166 1.7 Iterator it = q.iterator();
481 jsr166 1.5 while (it.hasNext()) {
482 dl 1.1 assertTrue(q.contains(it.next()));
483     ++i;
484     }
485     assertEquals(i, SIZE);
486     }
487    
488     /**
489     * iterator of empty set has no elements
490     */
491     public void testEmptyIterator() {
492     TreeSet q = new TreeSet();
493     int i = 0;
494 jsr166 1.7 Iterator it = q.iterator();
495 jsr166 1.5 while (it.hasNext()) {
496 dl 1.1 assertTrue(q.contains(it.next()));
497     ++i;
498     }
499 jsr166 1.24 assertEquals(0, i);
500 dl 1.1 }
501    
502     /**
503     * iterator.remove removes current element
504     */
505 jsr166 1.13 public void testIteratorRemove() {
506 dl 1.1 final TreeSet q = new TreeSet();
507     q.add(new Integer(2));
508     q.add(new Integer(1));
509     q.add(new Integer(3));
510    
511     Iterator it = q.iterator();
512     it.next();
513     it.remove();
514    
515     it = q.iterator();
516     assertEquals(it.next(), new Integer(2));
517     assertEquals(it.next(), new Integer(3));
518     assertFalse(it.hasNext());
519     }
520    
521     /**
522     * toString contains toStrings of elements
523     */
524     public void testToString() {
525     TreeSet q = populatedSet(SIZE);
526     String s = q.toString();
527     for (int i = 0; i < SIZE; ++i) {
528 jsr166 1.22 assertTrue(s.contains(String.valueOf(i)));
529 dl 1.1 }
530 jsr166 1.4 }
531 dl 1.1
532     /**
533 jsr166 1.4 * A deserialized serialized set has same elements
534 dl 1.1 */
535 jsr166 1.8 public void testSerialization() throws Exception {
536 jsr166 1.23 NavigableSet x = populatedSet(SIZE);
537     NavigableSet y = serialClone(x);
538    
539     assertTrue(x != y);
540     assertEquals(x.size(), y.size());
541     assertEquals(x, y);
542     assertEquals(y, x);
543     while (!x.isEmpty()) {
544     assertFalse(y.isEmpty());
545     assertEquals(x.pollFirst(), y.pollFirst());
546     }
547     assertTrue(y.isEmpty());
548 dl 1.1 }
549    
550     /**
551     * subSet returns set with keys in requested range
552     */
553     public void testSubSetContents() {
554     TreeSet set = set5();
555     SortedSet sm = set.subSet(two, four);
556     assertEquals(two, sm.first());
557     assertEquals(three, sm.last());
558     assertEquals(2, sm.size());
559     assertFalse(sm.contains(one));
560     assertTrue(sm.contains(two));
561     assertTrue(sm.contains(three));
562     assertFalse(sm.contains(four));
563     assertFalse(sm.contains(five));
564     Iterator i = sm.iterator();
565     Object k;
566     k = (Integer)(i.next());
567     assertEquals(two, k);
568     k = (Integer)(i.next());
569     assertEquals(three, k);
570     assertFalse(i.hasNext());
571     Iterator j = sm.iterator();
572     j.next();
573     j.remove();
574     assertFalse(set.contains(two));
575     assertEquals(4, set.size());
576     assertEquals(1, sm.size());
577     assertEquals(three, sm.first());
578     assertEquals(three, sm.last());
579     assertTrue(sm.remove(three));
580     assertTrue(sm.isEmpty());
581     assertEquals(3, set.size());
582     }
583    
584     public void testSubSetContents2() {
585     TreeSet set = set5();
586     SortedSet sm = set.subSet(two, three);
587     assertEquals(1, sm.size());
588     assertEquals(two, sm.first());
589     assertEquals(two, sm.last());
590     assertFalse(sm.contains(one));
591     assertTrue(sm.contains(two));
592     assertFalse(sm.contains(three));
593     assertFalse(sm.contains(four));
594     assertFalse(sm.contains(five));
595     Iterator i = sm.iterator();
596     Object k;
597     k = (Integer)(i.next());
598     assertEquals(two, k);
599     assertFalse(i.hasNext());
600     Iterator j = sm.iterator();
601     j.next();
602     j.remove();
603     assertFalse(set.contains(two));
604     assertEquals(4, set.size());
605     assertEquals(0, sm.size());
606     assertTrue(sm.isEmpty());
607     assertFalse(sm.remove(three));
608     assertEquals(4, set.size());
609     }
610    
611     /**
612     * headSet returns set with keys in requested range
613     */
614     public void testHeadSetContents() {
615     TreeSet set = set5();
616     SortedSet sm = set.headSet(four);
617     assertTrue(sm.contains(one));
618     assertTrue(sm.contains(two));
619     assertTrue(sm.contains(three));
620     assertFalse(sm.contains(four));
621     assertFalse(sm.contains(five));
622     Iterator i = sm.iterator();
623     Object k;
624     k = (Integer)(i.next());
625     assertEquals(one, k);
626     k = (Integer)(i.next());
627     assertEquals(two, k);
628     k = (Integer)(i.next());
629     assertEquals(three, k);
630     assertFalse(i.hasNext());
631     sm.clear();
632     assertTrue(sm.isEmpty());
633     assertEquals(2, set.size());
634     assertEquals(four, set.first());
635     }
636    
637     /**
638     * tailSet returns set with keys in requested range
639     */
640     public void testTailSetContents() {
641     TreeSet set = set5();
642     SortedSet sm = set.tailSet(two);
643     assertFalse(sm.contains(one));
644     assertTrue(sm.contains(two));
645     assertTrue(sm.contains(three));
646     assertTrue(sm.contains(four));
647     assertTrue(sm.contains(five));
648     Iterator i = sm.iterator();
649     Object k;
650     k = (Integer)(i.next());
651     assertEquals(two, k);
652     k = (Integer)(i.next());
653     assertEquals(three, k);
654     k = (Integer)(i.next());
655     assertEquals(four, k);
656     k = (Integer)(i.next());
657     assertEquals(five, k);
658     assertFalse(i.hasNext());
659    
660     SortedSet ssm = sm.tailSet(four);
661     assertEquals(four, ssm.first());
662     assertEquals(five, ssm.last());
663     assertTrue(ssm.remove(four));
664     assertEquals(1, ssm.size());
665     assertEquals(3, sm.size());
666     assertEquals(4, set.size());
667     }
668    
669 dl 1.2 Random rnd = new Random(666);
670     BitSet bs;
671    
672     /**
673     * Subsets of subsets subdivide correctly
674     */
675 jsr166 1.10 public void testRecursiveSubSets() throws Exception {
676 jsr166 1.16 int setSize = expensiveTests ? 1000 : 100;
677 jsr166 1.7 Class cl = TreeSet.class;
678 dl 1.2
679     NavigableSet<Integer> set = newSet(cl);
680     bs = new BitSet(setSize);
681    
682     populate(set, setSize);
683     check(set, 0, setSize - 1, true);
684     check(set.descendingSet(), 0, setSize - 1, false);
685    
686     mutateSet(set, 0, setSize - 1);
687     check(set, 0, setSize - 1, true);
688     check(set.descendingSet(), 0, setSize - 1, false);
689    
690 dl 1.3 bashSubSet(set.subSet(0, true, setSize, false),
691 dl 1.2 0, setSize - 1, true);
692     }
693    
694 jsr166 1.28 /**
695     * addAll is idempotent
696     */
697     public void testAddAll_idempotent() throws Exception {
698     Set x = populatedSet(SIZE);
699     Set y = new TreeSet(x);
700     y.addAll(x);
701     assertEquals(x, y);
702     assertEquals(y, x);
703     }
704    
705 jsr166 1.10 static NavigableSet<Integer> newSet(Class cl) throws Exception {
706     NavigableSet<Integer> result = (NavigableSet<Integer>) cl.newInstance();
707 jsr166 1.24 assertEquals(0, result.size());
708 dl 1.2 assertFalse(result.iterator().hasNext());
709     return result;
710     }
711    
712     void populate(NavigableSet<Integer> set, int limit) {
713     for (int i = 0, n = 2 * limit / 3; i < n; i++) {
714     int element = rnd.nextInt(limit);
715     put(set, element);
716     }
717     }
718    
719     void mutateSet(NavigableSet<Integer> set, int min, int max) {
720     int size = set.size();
721     int rangeSize = max - min + 1;
722    
723     // Remove a bunch of entries directly
724     for (int i = 0, n = rangeSize / 2; i < n; i++) {
725     remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
726     }
727    
728     // Remove a bunch of entries with iterator
729 jsr166 1.5 for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
730 dl 1.2 if (rnd.nextBoolean()) {
731     bs.clear(it.next());
732     it.remove();
733     }
734     }
735    
736     // Add entries till we're back to original size
737     while (set.size() < size) {
738     int element = min + rnd.nextInt(rangeSize);
739     assertTrue(element >= min && element<= max);
740     put(set, element);
741     }
742     }
743    
744     void mutateSubSet(NavigableSet<Integer> set, int min, int max) {
745     int size = set.size();
746     int rangeSize = max - min + 1;
747    
748     // Remove a bunch of entries directly
749     for (int i = 0, n = rangeSize / 2; i < n; i++) {
750     remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
751     }
752    
753     // Remove a bunch of entries with iterator
754 jsr166 1.5 for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
755 dl 1.2 if (rnd.nextBoolean()) {
756     bs.clear(it.next());
757     it.remove();
758     }
759     }
760    
761     // Add entries till we're back to original size
762     while (set.size() < size) {
763     int element = min - 5 + rnd.nextInt(rangeSize + 10);
764     if (element >= min && element<= max) {
765     put(set, element);
766     } else {
767     try {
768     set.add(element);
769 jsr166 1.10 shouldThrow();
770     } catch (IllegalArgumentException success) {}
771 dl 1.2 }
772     }
773     }
774    
775     void put(NavigableSet<Integer> set, int element) {
776     if (set.add(element))
777     bs.set(element);
778     }
779    
780     void remove(NavigableSet<Integer> set, int element) {
781     if (set.remove(element))
782     bs.clear(element);
783     }
784    
785     void bashSubSet(NavigableSet<Integer> set,
786     int min, int max, boolean ascending) {
787     check(set, min, max, ascending);
788     check(set.descendingSet(), min, max, !ascending);
789    
790     mutateSubSet(set, min, max);
791     check(set, min, max, ascending);
792     check(set.descendingSet(), min, max, !ascending);
793    
794     // Recurse
795     if (max - min < 2)
796     return;
797     int midPoint = (min + max) / 2;
798    
799     // headSet - pick direction and endpoint inclusion randomly
800     boolean incl = rnd.nextBoolean();
801 dl 1.3 NavigableSet<Integer> hm = set.headSet(midPoint, incl);
802 dl 1.2 if (ascending) {
803     if (rnd.nextBoolean())
804     bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true);
805     else
806     bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
807     false);
808     } else {
809     if (rnd.nextBoolean())
810     bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false);
811     else
812     bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
813     true);
814     }
815    
816     // tailSet - pick direction and endpoint inclusion randomly
817     incl = rnd.nextBoolean();
818 dl 1.3 NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
819 dl 1.2 if (ascending) {
820     if (rnd.nextBoolean())
821     bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true);
822     else
823     bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
824     false);
825     } else {
826     if (rnd.nextBoolean()) {
827     bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false);
828     } else {
829     bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
830     true);
831     }
832     }
833    
834     // subSet - pick direction and endpoint inclusion randomly
835     int rangeSize = max - min + 1;
836     int[] endpoints = new int[2];
837     endpoints[0] = min + rnd.nextInt(rangeSize);
838     endpoints[1] = min + rnd.nextInt(rangeSize);
839     Arrays.sort(endpoints);
840     boolean lowIncl = rnd.nextBoolean();
841     boolean highIncl = rnd.nextBoolean();
842     if (ascending) {
843 dl 1.3 NavigableSet<Integer> sm = set.subSet(
844 dl 1.2 endpoints[0], lowIncl, endpoints[1], highIncl);
845     if (rnd.nextBoolean())
846     bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
847     endpoints[1] - (highIncl ? 0 : 1), true);
848     else
849     bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
850     endpoints[1] - (highIncl ? 0 : 1), false);
851     } else {
852 dl 1.3 NavigableSet<Integer> sm = set.subSet(
853 dl 1.2 endpoints[1], highIncl, endpoints[0], lowIncl);
854     if (rnd.nextBoolean())
855     bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
856     endpoints[1] - (highIncl ? 0 : 1), false);
857     else
858     bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
859     endpoints[1] - (highIncl ? 0 : 1), true);
860     }
861     }
862    
863     /**
864     * min and max are both inclusive. If max < min, interval is empty.
865     */
866     void check(NavigableSet<Integer> set,
867     final int min, final int max, final boolean ascending) {
868 jsr166 1.21 class ReferenceSet {
869 dl 1.2 int lower(int element) {
870     return ascending ?
871     lowerAscending(element) : higherAscending(element);
872     }
873     int floor(int element) {
874     return ascending ?
875     floorAscending(element) : ceilingAscending(element);
876     }
877     int ceiling(int element) {
878     return ascending ?
879     ceilingAscending(element) : floorAscending(element);
880     }
881     int higher(int element) {
882     return ascending ?
883     higherAscending(element) : lowerAscending(element);
884     }
885     int first() {
886     return ascending ? firstAscending() : lastAscending();
887     }
888     int last() {
889     return ascending ? lastAscending() : firstAscending();
890     }
891     int lowerAscending(int element) {
892     return floorAscending(element - 1);
893     }
894     int floorAscending(int element) {
895     if (element < min)
896     return -1;
897     else if (element > max)
898     element = max;
899    
900     // BitSet should support this! Test would run much faster
901     while (element >= min) {
902     if (bs.get(element))
903 jsr166 1.15 return element;
904 dl 1.2 element--;
905     }
906     return -1;
907     }
908     int ceilingAscending(int element) {
909     if (element < min)
910     element = min;
911     else if (element > max)
912     return -1;
913     int result = bs.nextSetBit(element);
914     return result > max ? -1 : result;
915     }
916     int higherAscending(int element) {
917     return ceilingAscending(element + 1);
918     }
919     private int firstAscending() {
920     int result = ceilingAscending(min);
921     return result > max ? -1 : result;
922     }
923     private int lastAscending() {
924     int result = floorAscending(max);
925     return result < min ? -1 : result;
926     }
927     }
928     ReferenceSet rs = new ReferenceSet();
929    
930     // Test contents using containsElement
931     int size = 0;
932     for (int i = min; i <= max; i++) {
933     boolean bsContainsI = bs.get(i);
934     assertEquals(bsContainsI, set.contains(i));
935     if (bsContainsI)
936     size++;
937     }
938 jsr166 1.25 assertEquals(size, set.size());
939 dl 1.2
940     // Test contents using contains elementSet iterator
941     int size2 = 0;
942     int previousElement = -1;
943     for (int element : set) {
944     assertTrue(bs.get(element));
945     size2++;
946     assertTrue(previousElement < 0 || (ascending ?
947     element - previousElement > 0 : element - previousElement < 0));
948     previousElement = element;
949     }
950     assertEquals(size2, size);
951    
952     // Test navigation ops
953     for (int element = min - 1; element <= max + 1; element++) {
954     assertEq(set.lower(element), rs.lower(element));
955     assertEq(set.floor(element), rs.floor(element));
956     assertEq(set.higher(element), rs.higher(element));
957     assertEq(set.ceiling(element), rs.ceiling(element));
958     }
959    
960     // Test extrema
961     if (set.size() != 0) {
962     assertEq(set.first(), rs.first());
963     assertEq(set.last(), rs.last());
964     } else {
965     assertEq(rs.first(), -1);
966     assertEq(rs.last(), -1);
967     try {
968     set.first();
969 jsr166 1.10 shouldThrow();
970     } catch (NoSuchElementException success) {}
971 dl 1.2 try {
972     set.last();
973 jsr166 1.10 shouldThrow();
974     } catch (NoSuchElementException success) {}
975 dl 1.2 }
976     }
977    
978     static void assertEq(Integer i, int j) {
979     if (i == null)
980     assertEquals(j, -1);
981     else
982     assertEquals((int) i, j);
983     }
984    
985     static boolean eq(Integer i, int j) {
986     return i == null ? j == -1 : i == j;
987     }
988    
989 dl 1.1 }