ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeSetTest.java
Revision: 1.9
Committed: Sat Nov 21 10:29:50 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.8: +24 -33 lines
Log Message:
improve exception handling

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