ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListSetTest.java
Revision: 1.52
Committed: Wed Jan 27 01:57:24 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.51: +16 -16 lines
Log Message:
use diamond <> pervasively

File Contents

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