ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/TreeSetTest.java
Revision: 1.10
Committed: Sat Nov 21 17:38:06 2009 UTC (14 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +9 -20 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 jsr166 1.10 public void testRecursiveSubSets() throws Exception {
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 jsr166 1.10 static NavigableSet<Integer> newSet(Class cl) throws Exception {
692     NavigableSet<Integer> result = (NavigableSet<Integer>) cl.newInstance();
693 dl 1.2 assertEquals(result.size(), 0);
694     assertFalse(result.iterator().hasNext());
695     return result;
696     }
697    
698     void populate(NavigableSet<Integer> set, int limit) {
699     for (int i = 0, n = 2 * limit / 3; i < n; i++) {
700     int element = rnd.nextInt(limit);
701     put(set, element);
702     }
703     }
704    
705     void mutateSet(NavigableSet<Integer> set, int min, int max) {
706     int size = set.size();
707     int rangeSize = max - min + 1;
708    
709     // Remove a bunch of entries directly
710     for (int i = 0, n = rangeSize / 2; i < n; i++) {
711     remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
712     }
713    
714     // Remove a bunch of entries with iterator
715 jsr166 1.5 for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
716 dl 1.2 if (rnd.nextBoolean()) {
717     bs.clear(it.next());
718     it.remove();
719     }
720     }
721    
722     // Add entries till we're back to original size
723     while (set.size() < size) {
724     int element = min + rnd.nextInt(rangeSize);
725     assertTrue(element >= min && element<= max);
726     put(set, element);
727     }
728     }
729    
730     void mutateSubSet(NavigableSet<Integer> set, int min, int max) {
731     int size = set.size();
732     int rangeSize = max - min + 1;
733    
734     // Remove a bunch of entries directly
735     for (int i = 0, n = rangeSize / 2; i < n; i++) {
736     remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
737     }
738    
739     // Remove a bunch of entries with iterator
740 jsr166 1.5 for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
741 dl 1.2 if (rnd.nextBoolean()) {
742     bs.clear(it.next());
743     it.remove();
744     }
745     }
746    
747     // Add entries till we're back to original size
748     while (set.size() < size) {
749     int element = min - 5 + rnd.nextInt(rangeSize + 10);
750     if (element >= min && element<= max) {
751     put(set, element);
752     } else {
753     try {
754     set.add(element);
755 jsr166 1.10 shouldThrow();
756     } catch (IllegalArgumentException success) {}
757 dl 1.2 }
758     }
759     }
760    
761     void put(NavigableSet<Integer> set, int element) {
762     if (set.add(element))
763     bs.set(element);
764     }
765    
766     void remove(NavigableSet<Integer> set, int element) {
767     if (set.remove(element))
768     bs.clear(element);
769     }
770    
771     void bashSubSet(NavigableSet<Integer> set,
772     int min, int max, boolean ascending) {
773     check(set, min, max, ascending);
774     check(set.descendingSet(), min, max, !ascending);
775    
776     mutateSubSet(set, min, max);
777     check(set, min, max, ascending);
778     check(set.descendingSet(), min, max, !ascending);
779    
780     // Recurse
781     if (max - min < 2)
782     return;
783     int midPoint = (min + max) / 2;
784    
785     // headSet - pick direction and endpoint inclusion randomly
786     boolean incl = rnd.nextBoolean();
787 dl 1.3 NavigableSet<Integer> hm = set.headSet(midPoint, incl);
788 dl 1.2 if (ascending) {
789     if (rnd.nextBoolean())
790     bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true);
791     else
792     bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
793     false);
794     } else {
795     if (rnd.nextBoolean())
796     bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false);
797     else
798     bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
799     true);
800     }
801    
802     // tailSet - pick direction and endpoint inclusion randomly
803     incl = rnd.nextBoolean();
804 dl 1.3 NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
805 dl 1.2 if (ascending) {
806     if (rnd.nextBoolean())
807     bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true);
808     else
809     bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
810     false);
811     } else {
812     if (rnd.nextBoolean()) {
813     bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false);
814     } else {
815     bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
816     true);
817     }
818     }
819    
820     // subSet - pick direction and endpoint inclusion randomly
821     int rangeSize = max - min + 1;
822     int[] endpoints = new int[2];
823     endpoints[0] = min + rnd.nextInt(rangeSize);
824     endpoints[1] = min + rnd.nextInt(rangeSize);
825     Arrays.sort(endpoints);
826     boolean lowIncl = rnd.nextBoolean();
827     boolean highIncl = rnd.nextBoolean();
828     if (ascending) {
829 dl 1.3 NavigableSet<Integer> sm = set.subSet(
830 dl 1.2 endpoints[0], lowIncl, endpoints[1], highIncl);
831     if (rnd.nextBoolean())
832     bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
833     endpoints[1] - (highIncl ? 0 : 1), true);
834     else
835     bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
836     endpoints[1] - (highIncl ? 0 : 1), false);
837     } else {
838 dl 1.3 NavigableSet<Integer> sm = set.subSet(
839 dl 1.2 endpoints[1], highIncl, endpoints[0], lowIncl);
840     if (rnd.nextBoolean())
841     bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
842     endpoints[1] - (highIncl ? 0 : 1), false);
843     else
844     bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
845     endpoints[1] - (highIncl ? 0 : 1), true);
846     }
847     }
848    
849     /**
850     * min and max are both inclusive. If max < min, interval is empty.
851     */
852     void check(NavigableSet<Integer> set,
853     final int min, final int max, final boolean ascending) {
854     class ReferenceSet {
855     int lower(int element) {
856     return ascending ?
857     lowerAscending(element) : higherAscending(element);
858     }
859     int floor(int element) {
860     return ascending ?
861     floorAscending(element) : ceilingAscending(element);
862     }
863     int ceiling(int element) {
864     return ascending ?
865     ceilingAscending(element) : floorAscending(element);
866     }
867     int higher(int element) {
868     return ascending ?
869     higherAscending(element) : lowerAscending(element);
870     }
871     int first() {
872     return ascending ? firstAscending() : lastAscending();
873     }
874     int last() {
875     return ascending ? lastAscending() : firstAscending();
876     }
877     int lowerAscending(int element) {
878     return floorAscending(element - 1);
879     }
880     int floorAscending(int element) {
881     if (element < min)
882     return -1;
883     else if (element > max)
884     element = max;
885    
886     // BitSet should support this! Test would run much faster
887     while (element >= min) {
888     if (bs.get(element))
889     return(element);
890     element--;
891     }
892     return -1;
893     }
894     int ceilingAscending(int element) {
895     if (element < min)
896     element = min;
897     else if (element > max)
898     return -1;
899     int result = bs.nextSetBit(element);
900     return result > max ? -1 : result;
901     }
902     int higherAscending(int element) {
903     return ceilingAscending(element + 1);
904     }
905     private int firstAscending() {
906     int result = ceilingAscending(min);
907     return result > max ? -1 : result;
908     }
909     private int lastAscending() {
910     int result = floorAscending(max);
911     return result < min ? -1 : result;
912     }
913     }
914     ReferenceSet rs = new ReferenceSet();
915    
916     // Test contents using containsElement
917     int size = 0;
918     for (int i = min; i <= max; i++) {
919     boolean bsContainsI = bs.get(i);
920     assertEquals(bsContainsI, set.contains(i));
921     if (bsContainsI)
922     size++;
923     }
924     assertEquals(set.size(), size);
925    
926     // Test contents using contains elementSet iterator
927     int size2 = 0;
928     int previousElement = -1;
929     for (int element : set) {
930     assertTrue(bs.get(element));
931     size2++;
932     assertTrue(previousElement < 0 || (ascending ?
933     element - previousElement > 0 : element - previousElement < 0));
934     previousElement = element;
935     }
936     assertEquals(size2, size);
937    
938     // Test navigation ops
939     for (int element = min - 1; element <= max + 1; element++) {
940     assertEq(set.lower(element), rs.lower(element));
941     assertEq(set.floor(element), rs.floor(element));
942     assertEq(set.higher(element), rs.higher(element));
943     assertEq(set.ceiling(element), rs.ceiling(element));
944     }
945    
946     // Test extrema
947     if (set.size() != 0) {
948     assertEq(set.first(), rs.first());
949     assertEq(set.last(), rs.last());
950     } else {
951     assertEq(rs.first(), -1);
952     assertEq(rs.last(), -1);
953     try {
954     set.first();
955 jsr166 1.10 shouldThrow();
956     } catch (NoSuchElementException success) {}
957 dl 1.2 try {
958     set.last();
959 jsr166 1.10 shouldThrow();
960     } catch (NoSuchElementException success) {}
961 dl 1.2 }
962     }
963    
964     static void assertEq(Integer i, int j) {
965     if (i == null)
966     assertEquals(j, -1);
967     else
968     assertEquals((int) i, j);
969     }
970    
971     static boolean eq(Integer i, int j) {
972     return i == null ? j == -1 : i == j;
973     }
974    
975 dl 1.1 }