ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListSetTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ConcurrentSkipListSetTest.java (file contents):
Revision 1.1 by dl, Tue Dec 28 16:15:59 2004 UTC vs.
Revision 1.49 by jsr166, Sun Jan 7 22:59:18 2018 UTC

# Line 1 | Line 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
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6  
7 < import junit.framework.*;
8 < import java.util.*;
9 < import java.util.concurrent.*;
10 < import java.io.*;
7 > import java.util.Arrays;
8 > import java.util.BitSet;
9 > import java.util.Collection;
10 > import java.util.Comparator;
11 > import java.util.Iterator;
12 > import java.util.NavigableSet;
13 > import java.util.NoSuchElementException;
14 > import java.util.Random;
15 > import java.util.Set;
16 > import java.util.SortedSet;
17 > import java.util.concurrent.ConcurrentSkipListSet;
18 >
19 > import junit.framework.Test;
20 > import junit.framework.TestSuite;
21  
22   public class ConcurrentSkipListSetTest extends JSR166TestCase {
23      public static void main(String[] args) {
24 <        junit.textui.TestRunner.run (suite());  
24 >        main(suite(), args);
25      }
26      public static Test suite() {
27 <        return new TestSuite(ConcurrentSkipListSetTest.class);
27 >        return new TestSuite(ConcurrentSkipListSetTest.class);
28      }
29  
30 <    static class MyReverseComparator implements Comparator {
30 >    static class MyReverseComparator implements Comparator {
31          public int compare(Object x, Object y) {
32 <            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;
32 >            return ((Comparable)y).compareTo(x);
33          }
34      }
35  
36      /**
37 <     * Create a set of given size containing consecutive
38 <     * Integers 0 ... n.
37 >     * Returns a new set of given size containing consecutive
38 >     * Integers 0 ... n - 1.
39       */
40 <    private ConcurrentSkipListSet populatedSet(int n) {
41 <        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
40 >    private static ConcurrentSkipListSet<Integer> populatedSet(int n) {
41 >        ConcurrentSkipListSet<Integer> q = new ConcurrentSkipListSet<>();
42          assertTrue(q.isEmpty());
43 <        for(int i = n-1; i >= 0; i-=2)
44 <            assertTrue(q.add(new Integer(i)));
45 <        for(int i = (n & 1); i < n; i+=2)
46 <            assertTrue(q.add(new Integer(i)));
43 >        for (int i = n - 1; i >= 0; i -= 2)
44 >            assertTrue(q.add(new Integer(i)));
45 >        for (int i = (n & 1); i < n; i += 2)
46 >            assertTrue(q.add(new Integer(i)));
47          assertFalse(q.isEmpty());
48 <        assertEquals(n, q.size());
48 >        assertEquals(n, q.size());
49          return q;
50      }
51  
52      /**
53 <     * Create set of first 5 ints
53 >     * Returns a new set of first 5 ints.
54       */
55 <    private ConcurrentSkipListSet set5() {
55 >    private static ConcurrentSkipListSet set5() {
56          ConcurrentSkipListSet q = new ConcurrentSkipListSet();
57          assertTrue(q.isEmpty());
58          q.add(one);
# Line 54 | Line 60 | public class ConcurrentSkipListSetTest e
60          q.add(three);
61          q.add(four);
62          q.add(five);
63 <        assertEquals(5, q.size());
63 >        assertEquals(5, q.size());
64          return q;
65      }
66 <
66 >
67      /**
68       * A new set has unbounded capacity
69       */
# Line 70 | Line 76 | public class ConcurrentSkipListSetTest e
76       */
77      public void testConstructor3() {
78          try {
79 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet((Collection)null);
79 >            new ConcurrentSkipListSet((Collection)null);
80              shouldThrow();
81 <        }
76 <        catch (NullPointerException success) {}
81 >        } catch (NullPointerException success) {}
82      }
83  
84      /**
# Line 81 | Line 86 | public class ConcurrentSkipListSetTest e
86       */
87      public void testConstructor4() {
88          try {
89 <            Integer[] ints = new Integer[SIZE];
85 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
89 >            new ConcurrentSkipListSet(Arrays.asList(new Integer[SIZE]));
90              shouldThrow();
91 <        }
88 <        catch (NullPointerException success) {}
91 >        } catch (NullPointerException success) {}
92      }
93  
94      /**
95       * Initializing from Collection with some null elements throws NPE
96       */
97      public void testConstructor5() {
98 +        Integer[] ints = new Integer[SIZE];
99 +        for (int i = 0; i < SIZE - 1; ++i)
100 +            ints[i] = new Integer(i);
101          try {
102 <            Integer[] ints = new Integer[SIZE];
97 <            for (int i = 0; i < SIZE-1; ++i)
98 <                ints[i] = new Integer(i);
99 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
102 >            new ConcurrentSkipListSet(Arrays.asList(ints));
103              shouldThrow();
104 <        }
102 <        catch (NullPointerException success) {}
104 >        } catch (NullPointerException success) {}
105      }
106  
107      /**
108       * Set contains all elements of collection used to initialize
109       */
110      public void testConstructor6() {
111 <        try {
112 <            Integer[] ints = new Integer[SIZE];
113 <            for (int i = 0; i < SIZE; ++i)
114 <                ints[i] = new Integer(i);
115 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
116 <            for (int i = 0; i < SIZE; ++i)
115 <                assertEquals(ints[i], q.pollFirst());
116 <        }
117 <        finally {}
111 >        Integer[] ints = new Integer[SIZE];
112 >        for (int i = 0; i < SIZE; ++i)
113 >            ints[i] = new Integer(i);
114 >        ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
115 >        for (int i = 0; i < SIZE; ++i)
116 >            assertEquals(ints[i], q.pollFirst());
117      }
118  
119      /**
120       * The comparator used in constructor is used
121       */
122      public void testConstructor7() {
123 <        try {
124 <            MyReverseComparator cmp = new MyReverseComparator();
125 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet(cmp);
126 <            assertEquals(cmp, q.comparator());
127 <            Integer[] ints = new Integer[SIZE];
128 <            for (int i = 0; i < SIZE; ++i)
129 <                ints[i] = new Integer(i);
130 <            q.addAll(Arrays.asList(ints));
131 <            for (int i = SIZE-1; i >= 0; --i)
133 <                assertEquals(ints[i], q.pollFirst());
134 <        }
135 <        finally {}
123 >        MyReverseComparator cmp = new MyReverseComparator();
124 >        ConcurrentSkipListSet q = new ConcurrentSkipListSet(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      }
133  
134      /**
# Line 155 | Line 151 | public class ConcurrentSkipListSetTest e
151      public void testSize() {
152          ConcurrentSkipListSet q = populatedSet(SIZE);
153          for (int i = 0; i < SIZE; ++i) {
154 <            assertEquals(SIZE-i, q.size());
154 >            assertEquals(SIZE - i, q.size());
155              q.pollFirst();
156          }
157          for (int i = 0; i < SIZE; ++i) {
# Line 168 | Line 164 | public class ConcurrentSkipListSetTest e
164       * add(null) throws NPE
165       */
166      public void testAddNull() {
167 <        try {
168 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
167 >        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
168 >        try {
169              q.add(null);
170              shouldThrow();
171 <        } catch (NullPointerException success) { }  
171 >        } catch (NullPointerException success) {}
172      }
173  
174      /**
# Line 197 | Line 193 | public class ConcurrentSkipListSetTest e
193       * Add of non-Comparable throws CCE
194       */
195      public void testAddNonComparable() {
196 +        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
197          try {
201            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
202            q.add(new Object());
198              q.add(new Object());
199              q.add(new Object());
200              shouldThrow();
201 +        } catch (ClassCastException success) {
202 +            assertTrue(q.size() < 2);
203 +            for (int i = 0, size = q.size(); i < size; i++)
204 +                assertSame(Object.class, q.pollFirst().getClass());
205 +            assertNull(q.pollFirst());
206 +            assertTrue(q.isEmpty());
207 +            assertEquals(0, q.size());
208          }
207        catch(ClassCastException success) {}
209      }
210  
211      /**
212       * addAll(null) throws NPE
213       */
214      public void testAddAll1() {
215 +        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
216          try {
215            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
217              q.addAll(null);
218              shouldThrow();
219 <        }
219 <        catch (NullPointerException success) {}
219 >        } catch (NullPointerException success) {}
220      }
221 +
222      /**
223       * addAll of a collection with null elements throws NPE
224       */
225      public void testAddAll2() {
226 +        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
227 +        Integer[] ints = new Integer[SIZE];
228          try {
226            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
227            Integer[] ints = new Integer[SIZE];
229              q.addAll(Arrays.asList(ints));
230              shouldThrow();
231 <        }
231 <        catch (NullPointerException success) {}
231 >        } catch (NullPointerException success) {}
232      }
233 +
234      /**
235       * addAll of a collection with any null elements throws NPE after
236       * possibly adding some elements
237       */
238      public void testAddAll3() {
239 +        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
240 +        Integer[] ints = new Integer[SIZE];
241 +        for (int i = 0; i < SIZE - 1; ++i)
242 +            ints[i] = new Integer(i);
243          try {
239            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
240            Integer[] ints = new Integer[SIZE];
241            for (int i = 0; i < SIZE-1; ++i)
242                ints[i] = new Integer(i);
244              q.addAll(Arrays.asList(ints));
245              shouldThrow();
246 <        }
246 <        catch (NullPointerException success) {}
246 >        } catch (NullPointerException success) {}
247      }
248  
249      /**
250       * Set contains all elements of successful addAll
251       */
252      public void testAddAll5() {
253 <        try {
254 <            Integer[] empty = new Integer[0];
255 <            Integer[] ints = new Integer[SIZE];
256 <            for (int i = 0; i < SIZE; ++i)
257 <                ints[i] = new Integer(SIZE-1-i);
258 <            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
259 <            assertFalse(q.addAll(Arrays.asList(empty)));
260 <            assertTrue(q.addAll(Arrays.asList(ints)));
261 <            for (int i = 0; i < SIZE; ++i)
262 <                assertEquals(new Integer(i), q.pollFirst());
263 <        }
264 <        finally {}
253 >        Integer[] empty = new Integer[0];
254 >        Integer[] ints = new Integer[SIZE];
255 >        for (int i = 0; i < SIZE; ++i)
256 >            ints[i] = new Integer(SIZE - 1 - i);
257 >        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
258 >        assertFalse(q.addAll(Arrays.asList(empty)));
259 >        assertTrue(q.addAll(Arrays.asList(ints)));
260 >        for (int i = 0; i < SIZE; ++i)
261 >            assertEquals(i, q.pollFirst());
262      }
263  
264      /**
# Line 270 | Line 267 | public class ConcurrentSkipListSetTest e
267      public void testPollFirst() {
268          ConcurrentSkipListSet q = populatedSet(SIZE);
269          for (int i = 0; i < SIZE; ++i) {
270 <            assertEquals(i, ((Integer)q.pollFirst()).intValue());
270 >            assertEquals(i, q.pollFirst());
271          }
272 <        assertNull(q.pollFirst());
272 >        assertNull(q.pollFirst());
273      }
274  
275      /**
# Line 280 | Line 277 | public class ConcurrentSkipListSetTest e
277       */
278      public void testPollLast() {
279          ConcurrentSkipListSet q = populatedSet(SIZE);
280 <        for (int i = SIZE-1; i >= 0; --i) {
281 <            assertEquals(i, ((Integer)q.pollLast()).intValue());
280 >        for (int i = SIZE - 1; i >= 0; --i) {
281 >            assertEquals(i, q.pollLast());
282          }
283 <        assertNull(q.pollFirst());
283 >        assertNull(q.pollFirst());
284      }
285  
289
286      /**
287       * remove(x) removes x and returns true if present
288       */
289      public void testRemoveElement() {
290          ConcurrentSkipListSet q = populatedSet(SIZE);
291 <        for (int i = 1; i < SIZE; i+=2) {
292 <            assertTrue(q.remove(new Integer(i)));
293 <        }
294 <        for (int i = 0; i < SIZE; i+=2) {
295 <            assertTrue(q.remove(new Integer(i)));
296 <            assertFalse(q.remove(new Integer(i+1)));
291 >        for (int i = 1; i < SIZE; i += 2) {
292 >            assertTrue(q.contains(i));
293 >            assertTrue(q.remove(i));
294 >            assertFalse(q.contains(i));
295 >            assertTrue(q.contains(i - 1));
296 >        }
297 >        for (int i = 0; i < SIZE; i += 2) {
298 >            assertTrue(q.contains(i));
299 >            assertTrue(q.remove(i));
300 >            assertFalse(q.contains(i));
301 >            assertFalse(q.remove(i + 1));
302 >            assertFalse(q.contains(i + 1));
303          }
304          assertTrue(q.isEmpty());
305      }
306 <        
306 >
307      /**
308       * contains(x) reports true when elements added but not yet removed
309       */
# Line 356 | Line 358 | public class ConcurrentSkipListSetTest e
358                  assertTrue(changed);
359  
360              assertTrue(q.containsAll(p));
361 <            assertEquals(SIZE-i, q.size());
361 >            assertEquals(SIZE - i, q.size());
362              p.pollFirst();
363          }
364      }
# Line 369 | Line 371 | public class ConcurrentSkipListSetTest e
371              ConcurrentSkipListSet q = populatedSet(SIZE);
372              ConcurrentSkipListSet p = populatedSet(i);
373              assertTrue(q.removeAll(p));
374 <            assertEquals(SIZE-i, q.size());
374 >            assertEquals(SIZE - i, q.size());
375              for (int j = 0; j < i; ++j) {
376 <                Integer I = (Integer)(p.pollFirst());
377 <                assertFalse(q.contains(I));
376 >                Integer x = (Integer)(p.pollFirst());
377 >                assertFalse(q.contains(x));
378              }
379          }
380      }
381  
380    
381
382      /**
383       * lower returns preceding element
384       */
# Line 395 | Line 395 | public class ConcurrentSkipListSetTest e
395  
396          Object e4 = q.lower(zero);
397          assertNull(e4);
398
398      }
399  
400      /**
# Line 414 | Line 413 | public class ConcurrentSkipListSetTest e
413  
414          Object e4 = q.higher(six);
415          assertNull(e4);
417
416      }
417  
418      /**
# Line 433 | Line 431 | public class ConcurrentSkipListSetTest e
431  
432          Object e4 = q.floor(zero);
433          assertNull(e4);
436
434      }
435  
436      /**
# Line 452 | Line 449 | public class ConcurrentSkipListSetTest e
449  
450          Object e4 = q.ceiling(six);
451          assertNull(e4);
455
452      }
453  
454      /**
455 <     * toArray contains all elements
455 >     * toArray contains all elements in sorted order
456       */
457      public void testToArray() {
458          ConcurrentSkipListSet q = populatedSet(SIZE);
459 <        Object[] o = q.toArray();
460 <        Arrays.sort(o);
461 <        for(int i = 0; i < o.length; i++)
466 <            assertEquals(o[i], q.pollFirst());
459 >        Object[] o = q.toArray();
460 >        for (int i = 0; i < o.length; i++)
461 >            assertSame(o[i], q.pollFirst());
462      }
463  
464      /**
465 <     * toArray(a) contains all elements
465 >     * toArray(a) contains all elements in sorted order
466       */
467      public void testToArray2() {
468 <        ConcurrentSkipListSet q = populatedSet(SIZE);
469 <        Integer[] ints = new Integer[SIZE];
470 <        ints = (Integer[])q.toArray(ints);
471 <        Arrays.sort(ints);
472 <        for(int i = 0; i < ints.length; i++)
478 <            assertEquals(ints[i], q.pollFirst());
468 >        ConcurrentSkipListSet<Integer> q = populatedSet(SIZE);
469 >        Integer[] ints = new Integer[SIZE];
470 >        assertSame(ints, q.toArray(ints));
471 >        for (int i = 0; i < ints.length; i++)
472 >            assertSame(ints[i], q.pollFirst());
473      }
474 <    
474 >
475      /**
476       * iterator iterates through all elements
477       */
478      public void testIterator() {
479          ConcurrentSkipListSet q = populatedSet(SIZE);
480 <        int i = 0;
481 <        Iterator it = q.iterator();
482 <        while(it.hasNext()) {
480 >        Iterator it = q.iterator();
481 >        int i;
482 >        for (i = 0; it.hasNext(); i++)
483              assertTrue(q.contains(it.next()));
490            ++i;
491        }
484          assertEquals(i, SIZE);
485 +        assertIteratorExhausted(it);
486      }
487  
488      /**
489       * iterator of empty set has no elements
490       */
491      public void testEmptyIterator() {
492 <        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
493 <        int i = 0;
494 <        Iterator it = q.iterator();
502 <        while(it.hasNext()) {
503 <            assertTrue(q.contains(it.next()));
504 <            ++i;
505 <        }
506 <        assertEquals(i, 0);
492 >        NavigableSet s = new ConcurrentSkipListSet();
493 >        assertIteratorExhausted(s.iterator());
494 >        assertIteratorExhausted(s.descendingSet().iterator());
495      }
496  
497      /**
498       * iterator.remove removes current element
499       */
500 <    public void testIteratorRemove () {
500 >    public void testIteratorRemove() {
501          final ConcurrentSkipListSet q = new ConcurrentSkipListSet();
502          q.add(new Integer(2));
503          q.add(new Integer(1));
# Line 525 | Line 513 | public class ConcurrentSkipListSetTest e
513          assertFalse(it.hasNext());
514      }
515  
528
516      /**
517       * toString contains toStrings of elements
518       */
# Line 533 | Line 520 | public class ConcurrentSkipListSetTest e
520          ConcurrentSkipListSet q = populatedSet(SIZE);
521          String s = q.toString();
522          for (int i = 0; i < SIZE; ++i) {
523 <            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
523 >            assertTrue(s.contains(String.valueOf(i)));
524          }
525 <    }        
525 >    }
526  
527      /**
528 <     * A deserialized serialized set has same elements
528 >     * A cloned set equals original
529       */
530 <    public void testSerialization() {
531 <        ConcurrentSkipListSet q = populatedSet(SIZE);
532 <        try {
533 <            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
534 <            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
535 <            out.writeObject(q);
536 <            out.close();
537 <
538 <            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
539 <            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
540 <            ConcurrentSkipListSet r = (ConcurrentSkipListSet)in.readObject();
541 <            assertEquals(q.size(), r.size());
542 <            while (!q.isEmpty())
543 <                assertEquals(q.pollFirst(), r.pollFirst());
544 <        } catch(Exception e){
545 <            e.printStackTrace();
546 <            unexpectedException();
530 >    public void testClone() {
531 >        ConcurrentSkipListSet x = populatedSet(SIZE);
532 >        ConcurrentSkipListSet y = x.clone();
533 >
534 >        assertNotSame(x, y);
535 >        assertEquals(x.size(), y.size());
536 >        assertEquals(x, y);
537 >        assertEquals(y, x);
538 >        while (!x.isEmpty()) {
539 >            assertFalse(y.isEmpty());
540 >            assertEquals(x.pollFirst(), y.pollFirst());
541 >        }
542 >        assertTrue(y.isEmpty());
543 >    }
544 >
545 >    /**
546 >     * A deserialized/reserialized set equals original
547 >     */
548 >    public void testSerialization() throws Exception {
549 >        NavigableSet x = populatedSet(SIZE);
550 >        NavigableSet y = serialClone(x);
551 >
552 >        assertNotSame(x, y);
553 >        assertEquals(x.size(), y.size());
554 >        assertEquals(x, y);
555 >        assertEquals(y, x);
556 >        while (!x.isEmpty()) {
557 >            assertFalse(y.isEmpty());
558 >            assertEquals(x.pollFirst(), y.pollFirst());
559          }
560 +        assertTrue(y.isEmpty());
561      }
562  
563      /**
# Line 679 | Line 679 | public class ConcurrentSkipListSetTest e
679          assertEquals(4, set.size());
680      }
681  
682 +    Random rnd = new Random(666);
683 +
684 +    /**
685 +     * Subsets of subsets subdivide correctly
686 +     */
687 +    public void testRecursiveSubSets() throws Exception {
688 +        int setSize = expensiveTests ? 1000 : 100;
689 +        Class cl = ConcurrentSkipListSet.class;
690 +
691 +        NavigableSet<Integer> set = newSet(cl);
692 +        BitSet bs = new BitSet(setSize);
693 +
694 +        populate(set, setSize, bs);
695 +        check(set,                 0, setSize - 1, true, bs);
696 +        check(set.descendingSet(), 0, setSize - 1, false, bs);
697 +
698 +        mutateSet(set, 0, setSize - 1, bs);
699 +        check(set,                 0, setSize - 1, true, bs);
700 +        check(set.descendingSet(), 0, setSize - 1, false, bs);
701 +
702 +        bashSubSet(set.subSet(0, true, setSize, false),
703 +                   0, setSize - 1, true, bs);
704 +    }
705 +
706 +    /**
707 +     * addAll is idempotent
708 +     */
709 +    public void testAddAll_idempotent() throws Exception {
710 +        Set x = populatedSet(SIZE);
711 +        Set y = new ConcurrentSkipListSet(x);
712 +        y.addAll(x);
713 +        assertEquals(x, y);
714 +        assertEquals(y, x);
715 +    }
716 +
717 +    static NavigableSet<Integer> newSet(Class cl) throws Exception {
718 +        NavigableSet<Integer> result =
719 +            (NavigableSet<Integer>) cl.getConstructor().newInstance();
720 +        assertEquals(0, result.size());
721 +        assertFalse(result.iterator().hasNext());
722 +        return result;
723 +    }
724 +
725 +    void populate(NavigableSet<Integer> set, int limit, BitSet bs) {
726 +        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
727 +            int element = rnd.nextInt(limit);
728 +            put(set, element, bs);
729 +        }
730 +    }
731 +
732 +    void mutateSet(NavigableSet<Integer> set, int min, int max, BitSet bs) {
733 +        int size = set.size();
734 +        int rangeSize = max - min + 1;
735 +
736 +        // Remove a bunch of entries directly
737 +        for (int i = 0, n = rangeSize / 2; i < n; i++) {
738 +            remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs);
739 +        }
740 +
741 +        // Remove a bunch of entries with iterator
742 +        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
743 +            if (rnd.nextBoolean()) {
744 +                bs.clear(it.next());
745 +                it.remove();
746 +            }
747 +        }
748 +
749 +        // Add entries till we're back to original size
750 +        while (set.size() < size) {
751 +            int element = min + rnd.nextInt(rangeSize);
752 +            assertTrue(element >= min && element <= max);
753 +            put(set, element, bs);
754 +        }
755 +    }
756 +
757 +    void mutateSubSet(NavigableSet<Integer> set, int min, int max,
758 +                      BitSet bs) {
759 +        int size = set.size();
760 +        int rangeSize = max - min + 1;
761 +
762 +        // Remove a bunch of entries directly
763 +        for (int i = 0, n = rangeSize / 2; i < n; i++) {
764 +            remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs);
765 +        }
766 +
767 +        // Remove a bunch of entries with iterator
768 +        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
769 +            if (rnd.nextBoolean()) {
770 +                bs.clear(it.next());
771 +                it.remove();
772 +            }
773 +        }
774 +
775 +        // Add entries till we're back to original size
776 +        while (set.size() < size) {
777 +            int element = min - 5 + rnd.nextInt(rangeSize + 10);
778 +            if (element >= min && element <= max) {
779 +                put(set, element, bs);
780 +            } else {
781 +                try {
782 +                    set.add(element);
783 +                    shouldThrow();
784 +                } catch (IllegalArgumentException success) {}
785 +            }
786 +        }
787 +    }
788 +
789 +    void put(NavigableSet<Integer> set, int element, BitSet bs) {
790 +        if (set.add(element))
791 +            bs.set(element);
792 +    }
793 +
794 +    void remove(NavigableSet<Integer> set, int element, BitSet bs) {
795 +        if (set.remove(element))
796 +            bs.clear(element);
797 +    }
798 +
799 +    void bashSubSet(NavigableSet<Integer> set,
800 +                    int min, int max, boolean ascending,
801 +                    BitSet bs) {
802 +        check(set, min, max, ascending, bs);
803 +        check(set.descendingSet(), min, max, !ascending, bs);
804 +
805 +        mutateSubSet(set, min, max, bs);
806 +        check(set, min, max, ascending, bs);
807 +        check(set.descendingSet(), min, max, !ascending, bs);
808 +
809 +        // Recurse
810 +        if (max - min < 2)
811 +            return;
812 +        int midPoint = (min + max) / 2;
813 +
814 +        // headSet - pick direction and endpoint inclusion randomly
815 +        boolean incl = rnd.nextBoolean();
816 +        NavigableSet<Integer> hm = set.headSet(midPoint, incl);
817 +        if (ascending) {
818 +            if (rnd.nextBoolean())
819 +                bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true, bs);
820 +            else
821 +                bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
822 +                           false, bs);
823 +        } else {
824 +            if (rnd.nextBoolean())
825 +                bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false, bs);
826 +            else
827 +                bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
828 +                           true, bs);
829 +        }
830 +
831 +        // tailSet - pick direction and endpoint inclusion randomly
832 +        incl = rnd.nextBoolean();
833 +        NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
834 +        if (ascending) {
835 +            if (rnd.nextBoolean())
836 +                bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true, bs);
837 +            else
838 +                bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
839 +                           false, bs);
840 +        } else {
841 +            if (rnd.nextBoolean()) {
842 +                bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false, bs);
843 +            } else {
844 +                bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
845 +                           true, bs);
846 +            }
847 +        }
848 +
849 +        // subSet - pick direction and endpoint inclusion randomly
850 +        int rangeSize = max - min + 1;
851 +        int[] endpoints = new int[2];
852 +        endpoints[0] = min + rnd.nextInt(rangeSize);
853 +        endpoints[1] = min + rnd.nextInt(rangeSize);
854 +        Arrays.sort(endpoints);
855 +        boolean lowIncl = rnd.nextBoolean();
856 +        boolean highIncl = rnd.nextBoolean();
857 +        if (ascending) {
858 +            NavigableSet<Integer> sm = set.subSet(
859 +                endpoints[0], lowIncl, endpoints[1], highIncl);
860 +            if (rnd.nextBoolean())
861 +                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
862 +                           endpoints[1] - (highIncl ? 0 : 1), true, bs);
863 +            else
864 +                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
865 +                           endpoints[1] - (highIncl ? 0 : 1), false, bs);
866 +        } else {
867 +            NavigableSet<Integer> sm = set.subSet(
868 +                endpoints[1], highIncl, endpoints[0], lowIncl);
869 +            if (rnd.nextBoolean())
870 +                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
871 +                           endpoints[1] - (highIncl ? 0 : 1), false, bs);
872 +            else
873 +                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
874 +                           endpoints[1] - (highIncl ? 0 : 1), true, bs);
875 +        }
876 +    }
877 +
878 +    /**
879 +     * min and max are both inclusive.  If max < min, interval is empty.
880 +     */
881 +    void check(NavigableSet<Integer> set,
882 +               final int min, final int max, final boolean ascending,
883 +               final BitSet bs) {
884 +        class ReferenceSet {
885 +            int lower(int element) {
886 +                return ascending ?
887 +                    lowerAscending(element) : higherAscending(element);
888 +            }
889 +            int floor(int element) {
890 +                return ascending ?
891 +                    floorAscending(element) : ceilingAscending(element);
892 +            }
893 +            int ceiling(int element) {
894 +                return ascending ?
895 +                    ceilingAscending(element) : floorAscending(element);
896 +            }
897 +            int higher(int element) {
898 +                return ascending ?
899 +                    higherAscending(element) : lowerAscending(element);
900 +            }
901 +            int first() {
902 +                return ascending ? firstAscending() : lastAscending();
903 +            }
904 +            int last() {
905 +                return ascending ? lastAscending() : firstAscending();
906 +            }
907 +            int lowerAscending(int element) {
908 +                return floorAscending(element - 1);
909 +            }
910 +            int floorAscending(int element) {
911 +                if (element < min)
912 +                    return -1;
913 +                else if (element > max)
914 +                    element = max;
915 +
916 +                // BitSet should support this! Test would run much faster
917 +                while (element >= min) {
918 +                    if (bs.get(element))
919 +                        return element;
920 +                    element--;
921 +                }
922 +                return -1;
923 +            }
924 +            int ceilingAscending(int element) {
925 +                if (element < min)
926 +                    element = min;
927 +                else if (element > max)
928 +                    return -1;
929 +                int result = bs.nextSetBit(element);
930 +                return result > max ? -1 : result;
931 +            }
932 +            int higherAscending(int element) {
933 +                return ceilingAscending(element + 1);
934 +            }
935 +            private int firstAscending() {
936 +                int result = ceilingAscending(min);
937 +                return result > max ? -1 : result;
938 +            }
939 +            private int lastAscending() {
940 +                int result = floorAscending(max);
941 +                return result < min ? -1 : result;
942 +            }
943 +        }
944 +        ReferenceSet rs = new ReferenceSet();
945 +
946 +        // Test contents using containsElement
947 +        int size = 0;
948 +        for (int i = min; i <= max; i++) {
949 +            boolean bsContainsI = bs.get(i);
950 +            assertEquals(bsContainsI, set.contains(i));
951 +            if (bsContainsI)
952 +                size++;
953 +        }
954 +        assertEquals(size, set.size());
955 +
956 +        // Test contents using contains elementSet iterator
957 +        int size2 = 0;
958 +        int previousElement = -1;
959 +        for (int element : set) {
960 +            assertTrue(bs.get(element));
961 +            size2++;
962 +            assertTrue(previousElement < 0 || (ascending ?
963 +                element - previousElement > 0 : element - previousElement < 0));
964 +            previousElement = element;
965 +        }
966 +        assertEquals(size2, size);
967 +
968 +        // Test navigation ops
969 +        for (int element = min - 1; element <= max + 1; element++) {
970 +            assertEq(set.lower(element), rs.lower(element));
971 +            assertEq(set.floor(element), rs.floor(element));
972 +            assertEq(set.higher(element), rs.higher(element));
973 +            assertEq(set.ceiling(element), rs.ceiling(element));
974 +        }
975 +
976 +        // Test extrema
977 +        if (set.size() != 0) {
978 +            assertEq(set.first(), rs.first());
979 +            assertEq(set.last(), rs.last());
980 +        } else {
981 +            assertEq(rs.first(), -1);
982 +            assertEq(rs.last(),  -1);
983 +            try {
984 +                set.first();
985 +                shouldThrow();
986 +            } catch (NoSuchElementException success) {}
987 +            try {
988 +                set.last();
989 +                shouldThrow();
990 +            } catch (NoSuchElementException success) {}
991 +        }
992 +    }
993 +
994 +    static void assertEq(Integer i, int j) {
995 +        if (i == null)
996 +            assertEquals(j, -1);
997 +        else
998 +            assertEquals((int) i, j);
999 +    }
1000 +
1001 +    static boolean eq(Integer i, int j) {
1002 +        return (i == null) ? j == -1 : i == j;
1003 +    }
1004 +
1005   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines