ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListSetTest.java
Revision: 1.11
Committed: Sun Nov 22 18:57:17 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.10: +4 -8 lines
Log Message:
use autoboxing judiciously for readability

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