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

File Contents

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