ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.40
Committed: Fri Aug 4 03:00:20 2017 UTC (6 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.39: +2 -2 lines
Log Message:
cosmetic improvements

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.ArrayList;
8 import java.util.Arrays;
9 import java.util.BitSet;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import java.util.Map;
13 import java.util.NavigableMap;
14 import java.util.NavigableSet;
15 import java.util.NoSuchElementException;
16 import java.util.Random;
17 import java.util.Set;
18 import java.util.concurrent.ConcurrentSkipListMap;
19
20 import junit.framework.Test;
21 import junit.framework.TestSuite;
22
23 public class ConcurrentSkipListMapTest extends JSR166TestCase {
24 public static void main(String[] args) {
25 main(suite(), args);
26 }
27 public static Test suite() {
28 return new TestSuite(ConcurrentSkipListMapTest.class);
29 }
30
31 /**
32 * Returns a new map from Integers 1-5 to Strings "A"-"E".
33 */
34 private static ConcurrentSkipListMap map5() {
35 ConcurrentSkipListMap map = new ConcurrentSkipListMap();
36 assertTrue(map.isEmpty());
37 map.put(one, "A");
38 map.put(five, "E");
39 map.put(three, "C");
40 map.put(two, "B");
41 map.put(four, "D");
42 assertFalse(map.isEmpty());
43 assertEquals(5, map.size());
44 return map;
45 }
46
47 /**
48 * clear removes all pairs
49 */
50 public void testClear() {
51 ConcurrentSkipListMap map = map5();
52 map.clear();
53 assertEquals(0, map.size());
54 }
55
56 /**
57 * copy constructor creates map equal to source map
58 */
59 public void testConstructFromSorted() {
60 ConcurrentSkipListMap map = map5();
61 ConcurrentSkipListMap map2 = new ConcurrentSkipListMap(map);
62 assertEquals(map, map2);
63 }
64
65 /**
66 * Maps with same contents are equal
67 */
68 public void testEquals() {
69 ConcurrentSkipListMap map1 = map5();
70 ConcurrentSkipListMap map2 = map5();
71 assertEquals(map1, map2);
72 assertEquals(map2, map1);
73 map1.clear();
74 assertFalse(map1.equals(map2));
75 assertFalse(map2.equals(map1));
76 }
77
78 /**
79 * containsKey returns true for contained key
80 */
81 public void testContainsKey() {
82 ConcurrentSkipListMap map = map5();
83 assertTrue(map.containsKey(one));
84 assertFalse(map.containsKey(zero));
85 }
86
87 /**
88 * containsValue returns true for held values
89 */
90 public void testContainsValue() {
91 ConcurrentSkipListMap map = map5();
92 assertTrue(map.containsValue("A"));
93 assertFalse(map.containsValue("Z"));
94 }
95
96 /**
97 * get returns the correct element at the given key,
98 * or null if not present
99 */
100 public void testGet() {
101 ConcurrentSkipListMap map = map5();
102 assertEquals("A", (String)map.get(one));
103 ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
104 assertNull(empty.get(one));
105 }
106
107 /**
108 * isEmpty is true of empty map and false for non-empty
109 */
110 public void testIsEmpty() {
111 ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
112 ConcurrentSkipListMap map = map5();
113 assertTrue(empty.isEmpty());
114 assertFalse(map.isEmpty());
115 }
116
117 /**
118 * firstKey returns first key
119 */
120 public void testFirstKey() {
121 ConcurrentSkipListMap map = map5();
122 assertEquals(one, map.firstKey());
123 }
124
125 /**
126 * lastKey returns last key
127 */
128 public void testLastKey() {
129 ConcurrentSkipListMap map = map5();
130 assertEquals(five, map.lastKey());
131 }
132
133 /**
134 * keySet.toArray returns contains all keys
135 */
136 public void testKeySetToArray() {
137 ConcurrentSkipListMap map = map5();
138 Set s = map.keySet();
139 Object[] ar = s.toArray();
140 assertTrue(s.containsAll(Arrays.asList(ar)));
141 assertEquals(5, ar.length);
142 ar[0] = m10;
143 assertFalse(s.containsAll(Arrays.asList(ar)));
144 }
145
146 /**
147 * descendingkeySet.toArray returns contains all keys
148 */
149 public void testDescendingKeySetToArray() {
150 ConcurrentSkipListMap map = map5();
151 Set s = map.descendingKeySet();
152 Object[] ar = s.toArray();
153 assertEquals(5, ar.length);
154 assertTrue(s.containsAll(Arrays.asList(ar)));
155 ar[0] = m10;
156 assertFalse(s.containsAll(Arrays.asList(ar)));
157 }
158
159 /**
160 * keySet returns a Set containing all the keys
161 */
162 public void testKeySet() {
163 ConcurrentSkipListMap map = map5();
164 Set s = map.keySet();
165 assertEquals(5, s.size());
166 assertTrue(s.contains(one));
167 assertTrue(s.contains(two));
168 assertTrue(s.contains(three));
169 assertTrue(s.contains(four));
170 assertTrue(s.contains(five));
171 }
172
173 /**
174 * keySet is ordered
175 */
176 public void testKeySetOrder() {
177 ConcurrentSkipListMap map = map5();
178 Set s = map.keySet();
179 Iterator i = s.iterator();
180 Integer last = (Integer)i.next();
181 assertEquals(last, one);
182 int count = 1;
183 while (i.hasNext()) {
184 Integer k = (Integer)i.next();
185 assertTrue(last.compareTo(k) < 0);
186 last = k;
187 ++count;
188 }
189 assertEquals(5, count);
190 }
191
192 /**
193 * descending iterator of key set is inverse ordered
194 */
195 public void testKeySetDescendingIteratorOrder() {
196 ConcurrentSkipListMap map = map5();
197 NavigableSet s = map.navigableKeySet();
198 Iterator i = s.descendingIterator();
199 Integer last = (Integer)i.next();
200 assertEquals(last, five);
201 int count = 1;
202 while (i.hasNext()) {
203 Integer k = (Integer)i.next();
204 assertTrue(last.compareTo(k) > 0);
205 last = k;
206 ++count;
207 }
208 assertEquals(5, count);
209 }
210
211 /**
212 * descendingKeySet is ordered
213 */
214 public void testDescendingKeySetOrder() {
215 ConcurrentSkipListMap map = map5();
216 Set s = map.descendingKeySet();
217 Iterator i = s.iterator();
218 Integer last = (Integer)i.next();
219 assertEquals(last, five);
220 int count = 1;
221 while (i.hasNext()) {
222 Integer k = (Integer)i.next();
223 assertTrue(last.compareTo(k) > 0);
224 last = k;
225 ++count;
226 }
227 assertEquals(5, count);
228 }
229
230 /**
231 * descending iterator of descendingKeySet is ordered
232 */
233 public void testDescendingKeySetDescendingIteratorOrder() {
234 ConcurrentSkipListMap map = map5();
235 NavigableSet s = map.descendingKeySet();
236 Iterator i = s.descendingIterator();
237 Integer last = (Integer)i.next();
238 assertEquals(last, one);
239 int count = 1;
240 while (i.hasNext()) {
241 Integer k = (Integer)i.next();
242 assertTrue(last.compareTo(k) < 0);
243 last = k;
244 ++count;
245 }
246 assertEquals(5, count);
247 }
248
249 /**
250 * Values.toArray contains all values
251 */
252 public void testValuesToArray() {
253 ConcurrentSkipListMap map = map5();
254 Collection v = map.values();
255 Object[] ar = v.toArray();
256 ArrayList s = new ArrayList(Arrays.asList(ar));
257 assertEquals(5, ar.length);
258 assertTrue(s.contains("A"));
259 assertTrue(s.contains("B"));
260 assertTrue(s.contains("C"));
261 assertTrue(s.contains("D"));
262 assertTrue(s.contains("E"));
263 }
264
265 /**
266 * values collection contains all values
267 */
268 public void testValues() {
269 ConcurrentSkipListMap map = map5();
270 Collection s = map.values();
271 assertEquals(5, s.size());
272 assertTrue(s.contains("A"));
273 assertTrue(s.contains("B"));
274 assertTrue(s.contains("C"));
275 assertTrue(s.contains("D"));
276 assertTrue(s.contains("E"));
277 }
278
279 /**
280 * entrySet contains all pairs
281 */
282 public void testEntrySet() {
283 ConcurrentSkipListMap map = map5();
284 Set s = map.entrySet();
285 assertEquals(5, s.size());
286 Iterator it = s.iterator();
287 while (it.hasNext()) {
288 Map.Entry e = (Map.Entry) it.next();
289 assertTrue(
290 (e.getKey().equals(one) && e.getValue().equals("A")) ||
291 (e.getKey().equals(two) && e.getValue().equals("B")) ||
292 (e.getKey().equals(three) && e.getValue().equals("C")) ||
293 (e.getKey().equals(four) && e.getValue().equals("D")) ||
294 (e.getKey().equals(five) && e.getValue().equals("E")));
295 }
296 }
297
298 /**
299 * descendingEntrySet contains all pairs
300 */
301 public void testDescendingEntrySet() {
302 ConcurrentSkipListMap map = map5();
303 Set s = map.descendingMap().entrySet();
304 assertEquals(5, s.size());
305 Iterator it = s.iterator();
306 while (it.hasNext()) {
307 Map.Entry e = (Map.Entry) it.next();
308 assertTrue(
309 (e.getKey().equals(one) && e.getValue().equals("A")) ||
310 (e.getKey().equals(two) && e.getValue().equals("B")) ||
311 (e.getKey().equals(three) && e.getValue().equals("C")) ||
312 (e.getKey().equals(four) && e.getValue().equals("D")) ||
313 (e.getKey().equals(five) && e.getValue().equals("E")));
314 }
315 }
316
317 /**
318 * entrySet.toArray contains all entries
319 */
320 public void testEntrySetToArray() {
321 ConcurrentSkipListMap map = map5();
322 Set s = map.entrySet();
323 Object[] ar = s.toArray();
324 assertEquals(5, ar.length);
325 for (int i = 0; i < 5; ++i) {
326 assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
327 assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
328 }
329 }
330
331 /**
332 * descendingEntrySet.toArray contains all entries
333 */
334 public void testDescendingEntrySetToArray() {
335 ConcurrentSkipListMap map = map5();
336 Set s = map.descendingMap().entrySet();
337 Object[] ar = s.toArray();
338 assertEquals(5, ar.length);
339 for (int i = 0; i < 5; ++i) {
340 assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
341 assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
342 }
343 }
344
345 /**
346 * putAll adds all key-value pairs from the given map
347 */
348 public void testPutAll() {
349 ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
350 ConcurrentSkipListMap map = map5();
351 empty.putAll(map);
352 assertEquals(5, empty.size());
353 assertTrue(empty.containsKey(one));
354 assertTrue(empty.containsKey(two));
355 assertTrue(empty.containsKey(three));
356 assertTrue(empty.containsKey(four));
357 assertTrue(empty.containsKey(five));
358 }
359
360 /**
361 * putIfAbsent works when the given key is not present
362 */
363 public void testPutIfAbsent() {
364 ConcurrentSkipListMap map = map5();
365 map.putIfAbsent(six, "Z");
366 assertTrue(map.containsKey(six));
367 }
368
369 /**
370 * putIfAbsent does not add the pair if the key is already present
371 */
372 public void testPutIfAbsent2() {
373 ConcurrentSkipListMap map = map5();
374 assertEquals("A", map.putIfAbsent(one, "Z"));
375 }
376
377 /**
378 * replace fails when the given key is not present
379 */
380 public void testReplace() {
381 ConcurrentSkipListMap map = map5();
382 assertNull(map.replace(six, "Z"));
383 assertFalse(map.containsKey(six));
384 }
385
386 /**
387 * replace succeeds if the key is already present
388 */
389 public void testReplace2() {
390 ConcurrentSkipListMap map = map5();
391 assertNotNull(map.replace(one, "Z"));
392 assertEquals("Z", map.get(one));
393 }
394
395 /**
396 * replace value fails when the given key not mapped to expected value
397 */
398 public void testReplaceValue() {
399 ConcurrentSkipListMap map = map5();
400 assertEquals("A", map.get(one));
401 assertFalse(map.replace(one, "Z", "Z"));
402 assertEquals("A", map.get(one));
403 }
404
405 /**
406 * replace value succeeds when the given key mapped to expected value
407 */
408 public void testReplaceValue2() {
409 ConcurrentSkipListMap map = map5();
410 assertEquals("A", map.get(one));
411 assertTrue(map.replace(one, "A", "Z"));
412 assertEquals("Z", map.get(one));
413 }
414
415 /**
416 * remove removes the correct key-value pair from the map
417 */
418 public void testRemove() {
419 ConcurrentSkipListMap map = map5();
420 map.remove(five);
421 assertEquals(4, map.size());
422 assertFalse(map.containsKey(five));
423 }
424
425 /**
426 * remove(key,value) removes only if pair present
427 */
428 public void testRemove2() {
429 ConcurrentSkipListMap map = map5();
430 assertTrue(map.containsKey(five));
431 assertEquals("E", map.get(five));
432 map.remove(five, "E");
433 assertEquals(4, map.size());
434 assertFalse(map.containsKey(five));
435 map.remove(four, "A");
436 assertEquals(4, map.size());
437 assertTrue(map.containsKey(four));
438 }
439
440 /**
441 * lowerEntry returns preceding entry.
442 */
443 public void testLowerEntry() {
444 ConcurrentSkipListMap map = map5();
445 Map.Entry e1 = map.lowerEntry(three);
446 assertEquals(two, e1.getKey());
447
448 Map.Entry e2 = map.lowerEntry(six);
449 assertEquals(five, e2.getKey());
450
451 Map.Entry e3 = map.lowerEntry(one);
452 assertNull(e3);
453
454 Map.Entry e4 = map.lowerEntry(zero);
455 assertNull(e4);
456 }
457
458 /**
459 * higherEntry returns next entry.
460 */
461 public void testHigherEntry() {
462 ConcurrentSkipListMap map = map5();
463 Map.Entry e1 = map.higherEntry(three);
464 assertEquals(four, e1.getKey());
465
466 Map.Entry e2 = map.higherEntry(zero);
467 assertEquals(one, e2.getKey());
468
469 Map.Entry e3 = map.higherEntry(five);
470 assertNull(e3);
471
472 Map.Entry e4 = map.higherEntry(six);
473 assertNull(e4);
474 }
475
476 /**
477 * floorEntry returns preceding entry.
478 */
479 public void testFloorEntry() {
480 ConcurrentSkipListMap map = map5();
481 Map.Entry e1 = map.floorEntry(three);
482 assertEquals(three, e1.getKey());
483
484 Map.Entry e2 = map.floorEntry(six);
485 assertEquals(five, e2.getKey());
486
487 Map.Entry e3 = map.floorEntry(one);
488 assertEquals(one, e3.getKey());
489
490 Map.Entry e4 = map.floorEntry(zero);
491 assertNull(e4);
492 }
493
494 /**
495 * ceilingEntry returns next entry.
496 */
497 public void testCeilingEntry() {
498 ConcurrentSkipListMap map = map5();
499 Map.Entry e1 = map.ceilingEntry(three);
500 assertEquals(three, e1.getKey());
501
502 Map.Entry e2 = map.ceilingEntry(zero);
503 assertEquals(one, e2.getKey());
504
505 Map.Entry e3 = map.ceilingEntry(five);
506 assertEquals(five, e3.getKey());
507
508 Map.Entry e4 = map.ceilingEntry(six);
509 assertNull(e4);
510 }
511
512 /**
513 * lowerEntry, higherEntry, ceilingEntry, and floorEntry return
514 * immutable entries
515 */
516 public void testEntryImmutability() {
517 ConcurrentSkipListMap map = map5();
518 Map.Entry e = map.lowerEntry(three);
519 assertEquals(two, e.getKey());
520 try {
521 e.setValue("X");
522 shouldThrow();
523 } catch (UnsupportedOperationException success) {}
524 e = map.higherEntry(zero);
525 assertEquals(one, e.getKey());
526 try {
527 e.setValue("X");
528 shouldThrow();
529 } catch (UnsupportedOperationException success) {}
530 e = map.floorEntry(one);
531 assertEquals(one, e.getKey());
532 try {
533 e.setValue("X");
534 shouldThrow();
535 } catch (UnsupportedOperationException success) {}
536 e = map.ceilingEntry(five);
537 assertEquals(five, e.getKey());
538 try {
539 e.setValue("X");
540 shouldThrow();
541 } catch (UnsupportedOperationException success) {}
542 }
543
544 /**
545 * lowerKey returns preceding element
546 */
547 public void testLowerKey() {
548 ConcurrentSkipListMap q = map5();
549 Object e1 = q.lowerKey(three);
550 assertEquals(two, e1);
551
552 Object e2 = q.lowerKey(six);
553 assertEquals(five, e2);
554
555 Object e3 = q.lowerKey(one);
556 assertNull(e3);
557
558 Object e4 = q.lowerKey(zero);
559 assertNull(e4);
560 }
561
562 /**
563 * higherKey returns next element
564 */
565 public void testHigherKey() {
566 ConcurrentSkipListMap q = map5();
567 Object e1 = q.higherKey(three);
568 assertEquals(four, e1);
569
570 Object e2 = q.higherKey(zero);
571 assertEquals(one, e2);
572
573 Object e3 = q.higherKey(five);
574 assertNull(e3);
575
576 Object e4 = q.higherKey(six);
577 assertNull(e4);
578 }
579
580 /**
581 * floorKey returns preceding element
582 */
583 public void testFloorKey() {
584 ConcurrentSkipListMap q = map5();
585 Object e1 = q.floorKey(three);
586 assertEquals(three, e1);
587
588 Object e2 = q.floorKey(six);
589 assertEquals(five, e2);
590
591 Object e3 = q.floorKey(one);
592 assertEquals(one, e3);
593
594 Object e4 = q.floorKey(zero);
595 assertNull(e4);
596 }
597
598 /**
599 * ceilingKey returns next element
600 */
601 public void testCeilingKey() {
602 ConcurrentSkipListMap q = map5();
603 Object e1 = q.ceilingKey(three);
604 assertEquals(three, e1);
605
606 Object e2 = q.ceilingKey(zero);
607 assertEquals(one, e2);
608
609 Object e3 = q.ceilingKey(five);
610 assertEquals(five, e3);
611
612 Object e4 = q.ceilingKey(six);
613 assertNull(e4);
614 }
615
616 /**
617 * pollFirstEntry returns entries in order
618 */
619 public void testPollFirstEntry() {
620 ConcurrentSkipListMap map = map5();
621 Map.Entry e = map.pollFirstEntry();
622 assertEquals(one, e.getKey());
623 assertEquals("A", e.getValue());
624 e = map.pollFirstEntry();
625 assertEquals(two, e.getKey());
626 map.put(one, "A");
627 e = map.pollFirstEntry();
628 assertEquals(one, e.getKey());
629 assertEquals("A", e.getValue());
630 e = map.pollFirstEntry();
631 assertEquals(three, e.getKey());
632 map.remove(four);
633 e = map.pollFirstEntry();
634 assertEquals(five, e.getKey());
635 try {
636 e.setValue("A");
637 shouldThrow();
638 } catch (UnsupportedOperationException success) {}
639 e = map.pollFirstEntry();
640 assertNull(e);
641 }
642
643 /**
644 * pollLastEntry returns entries in order
645 */
646 public void testPollLastEntry() {
647 ConcurrentSkipListMap map = map5();
648 Map.Entry e = map.pollLastEntry();
649 assertEquals(five, e.getKey());
650 assertEquals("E", e.getValue());
651 e = map.pollLastEntry();
652 assertEquals(four, e.getKey());
653 map.put(five, "E");
654 e = map.pollLastEntry();
655 assertEquals(five, e.getKey());
656 assertEquals("E", e.getValue());
657 e = map.pollLastEntry();
658 assertEquals(three, e.getKey());
659 map.remove(two);
660 e = map.pollLastEntry();
661 assertEquals(one, e.getKey());
662 try {
663 e.setValue("E");
664 shouldThrow();
665 } catch (UnsupportedOperationException success) {}
666 e = map.pollLastEntry();
667 assertNull(e);
668 }
669
670 /**
671 * size returns the correct values
672 */
673 public void testSize() {
674 ConcurrentSkipListMap map = map5();
675 ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
676 assertEquals(0, empty.size());
677 assertEquals(5, map.size());
678 }
679
680 /**
681 * toString contains toString of elements
682 */
683 public void testToString() {
684 ConcurrentSkipListMap map = map5();
685 String s = map.toString();
686 for (int i = 1; i <= 5; ++i) {
687 assertTrue(s.contains(String.valueOf(i)));
688 }
689 }
690
691 // Exception tests
692
693 /**
694 * get(null) of nonempty map throws NPE
695 */
696 public void testGet_NullPointerException() {
697 ConcurrentSkipListMap c = map5();
698 try {
699 c.get(null);
700 shouldThrow();
701 } catch (NullPointerException success) {}
702 }
703
704 /**
705 * containsKey(null) of nonempty map throws NPE
706 */
707 public void testContainsKey_NullPointerException() {
708 ConcurrentSkipListMap c = map5();
709 try {
710 c.containsKey(null);
711 shouldThrow();
712 } catch (NullPointerException success) {}
713 }
714
715 /**
716 * containsValue(null) throws NPE
717 */
718 public void testContainsValue_NullPointerException() {
719 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
720 try {
721 c.containsValue(null);
722 shouldThrow();
723 } catch (NullPointerException success) {}
724 }
725
726 /**
727 * put(null,x) throws NPE
728 */
729 public void testPut1_NullPointerException() {
730 ConcurrentSkipListMap c = map5();
731 try {
732 c.put(null, "whatever");
733 shouldThrow();
734 } catch (NullPointerException success) {}
735 }
736
737 /**
738 * putIfAbsent(null, x) throws NPE
739 */
740 public void testPutIfAbsent1_NullPointerException() {
741 ConcurrentSkipListMap c = map5();
742 try {
743 c.putIfAbsent(null, "whatever");
744 shouldThrow();
745 } catch (NullPointerException success) {}
746 }
747
748 /**
749 * replace(null, x) throws NPE
750 */
751 public void testReplace_NullPointerException() {
752 ConcurrentSkipListMap c = map5();
753 try {
754 c.replace(null, "whatever");
755 shouldThrow();
756 } catch (NullPointerException success) {}
757 }
758
759 /**
760 * replace(null, x, y) throws NPE
761 */
762 public void testReplaceValue_NullPointerException() {
763 ConcurrentSkipListMap c = map5();
764 try {
765 c.replace(null, one, "whatever");
766 shouldThrow();
767 } catch (NullPointerException success) {}
768 }
769
770 /**
771 * remove(null) throws NPE
772 */
773 public void testRemove1_NullPointerException() {
774 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
775 c.put("sadsdf", "asdads");
776 try {
777 c.remove(null);
778 shouldThrow();
779 } catch (NullPointerException success) {}
780 }
781
782 /**
783 * remove(null, x) throws NPE
784 */
785 public void testRemove2_NullPointerException() {
786 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
787 c.put("sadsdf", "asdads");
788 try {
789 c.remove(null, "whatever");
790 shouldThrow();
791 } catch (NullPointerException success) {}
792 }
793
794 /**
795 * remove(x, null) returns false
796 */
797 public void testRemove3() {
798 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
799 c.put("sadsdf", "asdads");
800 assertFalse(c.remove("sadsdf", null));
801 }
802
803 /**
804 * A cloned map equals original
805 */
806 public void testClone() {
807 ConcurrentSkipListMap x = map5();
808 ConcurrentSkipListMap y = x.clone();
809
810 assertNotSame(x, y);
811 assertEquals(x.size(), y.size());
812 assertEquals(x.toString(), y.toString());
813 assertEquals(x, y);
814 assertEquals(y, x);
815 y.clear();
816 assertTrue(y.isEmpty());
817 assertFalse(x.equals(y));
818 }
819
820 /**
821 * A deserialized/reserialized map equals original
822 */
823 public void testSerialization() throws Exception {
824 NavigableMap x = map5();
825 NavigableMap y = serialClone(x);
826
827 assertNotSame(x, y);
828 assertEquals(x.size(), y.size());
829 assertEquals(x.toString(), y.toString());
830 assertEquals(x, y);
831 assertEquals(y, x);
832 y.clear();
833 assertTrue(y.isEmpty());
834 assertFalse(x.equals(y));
835 }
836
837 /**
838 * subMap returns map with keys in requested range
839 */
840 public void testSubMapContents() {
841 ConcurrentSkipListMap map = map5();
842 NavigableMap sm = map.subMap(two, true, four, false);
843 assertEquals(two, sm.firstKey());
844 assertEquals(three, sm.lastKey());
845 assertEquals(2, sm.size());
846 assertFalse(sm.containsKey(one));
847 assertTrue(sm.containsKey(two));
848 assertTrue(sm.containsKey(three));
849 assertFalse(sm.containsKey(four));
850 assertFalse(sm.containsKey(five));
851 Iterator i = sm.keySet().iterator();
852 Object k;
853 k = (Integer)(i.next());
854 assertEquals(two, k);
855 k = (Integer)(i.next());
856 assertEquals(three, k);
857 assertFalse(i.hasNext());
858 Iterator r = sm.descendingKeySet().iterator();
859 k = (Integer)(r.next());
860 assertEquals(three, k);
861 k = (Integer)(r.next());
862 assertEquals(two, k);
863 assertFalse(r.hasNext());
864
865 Iterator j = sm.keySet().iterator();
866 j.next();
867 j.remove();
868 assertFalse(map.containsKey(two));
869 assertEquals(4, map.size());
870 assertEquals(1, sm.size());
871 assertEquals(three, sm.firstKey());
872 assertEquals(three, sm.lastKey());
873 assertEquals("C", sm.remove(three));
874 assertTrue(sm.isEmpty());
875 assertEquals(3, map.size());
876 }
877
878 public void testSubMapContents2() {
879 ConcurrentSkipListMap map = map5();
880 NavigableMap sm = map.subMap(two, true, three, false);
881 assertEquals(1, sm.size());
882 assertEquals(two, sm.firstKey());
883 assertEquals(two, sm.lastKey());
884 assertFalse(sm.containsKey(one));
885 assertTrue(sm.containsKey(two));
886 assertFalse(sm.containsKey(three));
887 assertFalse(sm.containsKey(four));
888 assertFalse(sm.containsKey(five));
889 Iterator i = sm.keySet().iterator();
890 Object k;
891 k = (Integer)(i.next());
892 assertEquals(two, k);
893 assertFalse(i.hasNext());
894 Iterator r = sm.descendingKeySet().iterator();
895 k = (Integer)(r.next());
896 assertEquals(two, k);
897 assertFalse(r.hasNext());
898
899 Iterator j = sm.keySet().iterator();
900 j.next();
901 j.remove();
902 assertFalse(map.containsKey(two));
903 assertEquals(4, map.size());
904 assertEquals(0, sm.size());
905 assertTrue(sm.isEmpty());
906 assertSame(sm.remove(three), null);
907 assertEquals(4, map.size());
908 }
909
910 /**
911 * headMap returns map with keys in requested range
912 */
913 public void testHeadMapContents() {
914 ConcurrentSkipListMap map = map5();
915 NavigableMap sm = map.headMap(four, false);
916 assertTrue(sm.containsKey(one));
917 assertTrue(sm.containsKey(two));
918 assertTrue(sm.containsKey(three));
919 assertFalse(sm.containsKey(four));
920 assertFalse(sm.containsKey(five));
921 Iterator i = sm.keySet().iterator();
922 Object k;
923 k = (Integer)(i.next());
924 assertEquals(one, k);
925 k = (Integer)(i.next());
926 assertEquals(two, k);
927 k = (Integer)(i.next());
928 assertEquals(three, k);
929 assertFalse(i.hasNext());
930 sm.clear();
931 assertTrue(sm.isEmpty());
932 assertEquals(2, map.size());
933 assertEquals(four, map.firstKey());
934 }
935
936 /**
937 * tailMap returns map with keys in requested range
938 */
939 public void testTailMapContents() {
940 ConcurrentSkipListMap map = map5();
941 NavigableMap sm = map.tailMap(two, true);
942 assertFalse(sm.containsKey(one));
943 assertTrue(sm.containsKey(two));
944 assertTrue(sm.containsKey(three));
945 assertTrue(sm.containsKey(four));
946 assertTrue(sm.containsKey(five));
947 Iterator i = sm.keySet().iterator();
948 Object k;
949 k = (Integer)(i.next());
950 assertEquals(two, k);
951 k = (Integer)(i.next());
952 assertEquals(three, k);
953 k = (Integer)(i.next());
954 assertEquals(four, k);
955 k = (Integer)(i.next());
956 assertEquals(five, k);
957 assertFalse(i.hasNext());
958 Iterator r = sm.descendingKeySet().iterator();
959 k = (Integer)(r.next());
960 assertEquals(five, k);
961 k = (Integer)(r.next());
962 assertEquals(four, k);
963 k = (Integer)(r.next());
964 assertEquals(three, k);
965 k = (Integer)(r.next());
966 assertEquals(two, k);
967 assertFalse(r.hasNext());
968
969 Iterator ei = sm.entrySet().iterator();
970 Map.Entry e;
971 e = (Map.Entry)(ei.next());
972 assertEquals(two, e.getKey());
973 assertEquals("B", e.getValue());
974 e = (Map.Entry)(ei.next());
975 assertEquals(three, e.getKey());
976 assertEquals("C", e.getValue());
977 e = (Map.Entry)(ei.next());
978 assertEquals(four, e.getKey());
979 assertEquals("D", e.getValue());
980 e = (Map.Entry)(ei.next());
981 assertEquals(five, e.getKey());
982 assertEquals("E", e.getValue());
983 assertFalse(i.hasNext());
984
985 NavigableMap ssm = sm.tailMap(four, true);
986 assertEquals(four, ssm.firstKey());
987 assertEquals(five, ssm.lastKey());
988 assertEquals("D", ssm.remove(four));
989 assertEquals(1, ssm.size());
990 assertEquals(3, sm.size());
991 assertEquals(4, map.size());
992 }
993
994 Random rnd = new Random(666);
995 BitSet bs;
996
997 /**
998 * Submaps of submaps subdivide correctly
999 */
1000 public void testRecursiveSubMaps() throws Exception {
1001 int mapSize = expensiveTests ? 1000 : 100;
1002 Class cl = ConcurrentSkipListMap.class;
1003 NavigableMap<Integer, Integer> map = newMap(cl);
1004 bs = new BitSet(mapSize);
1005
1006 populate(map, mapSize);
1007 check(map, 0, mapSize - 1, true);
1008 check(map.descendingMap(), 0, mapSize - 1, false);
1009
1010 mutateMap(map, 0, mapSize - 1);
1011 check(map, 0, mapSize - 1, true);
1012 check(map.descendingMap(), 0, mapSize - 1, false);
1013
1014 bashSubMap(map.subMap(0, true, mapSize, false),
1015 0, mapSize - 1, true);
1016 }
1017
1018 static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
1019 NavigableMap<Integer, Integer> result =
1020 (NavigableMap<Integer, Integer>) cl.getConstructor().newInstance();
1021 assertEquals(0, result.size());
1022 assertFalse(result.keySet().iterator().hasNext());
1023 return result;
1024 }
1025
1026 void populate(NavigableMap<Integer, Integer> map, int limit) {
1027 for (int i = 0, n = 2 * limit / 3; i < n; i++) {
1028 int key = rnd.nextInt(limit);
1029 put(map, key);
1030 }
1031 }
1032
1033 void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
1034 int size = map.size();
1035 int rangeSize = max - min + 1;
1036
1037 // Remove a bunch of entries directly
1038 for (int i = 0, n = rangeSize / 2; i < n; i++) {
1039 remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
1040 }
1041
1042 // Remove a bunch of entries with iterator
1043 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
1044 if (rnd.nextBoolean()) {
1045 bs.clear(it.next());
1046 it.remove();
1047 }
1048 }
1049
1050 // Add entries till we're back to original size
1051 while (map.size() < size) {
1052 int key = min + rnd.nextInt(rangeSize);
1053 assertTrue(key >= min && key <= max);
1054 put(map, key);
1055 }
1056 }
1057
1058 void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
1059 int size = map.size();
1060 int rangeSize = max - min + 1;
1061
1062 // Remove a bunch of entries directly
1063 for (int i = 0, n = rangeSize / 2; i < n; i++) {
1064 remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
1065 }
1066
1067 // Remove a bunch of entries with iterator
1068 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
1069 if (rnd.nextBoolean()) {
1070 bs.clear(it.next());
1071 it.remove();
1072 }
1073 }
1074
1075 // Add entries till we're back to original size
1076 while (map.size() < size) {
1077 int key = min - 5 + rnd.nextInt(rangeSize + 10);
1078 if (key >= min && key <= max) {
1079 put(map, key);
1080 } else {
1081 try {
1082 map.put(key, 2 * key);
1083 shouldThrow();
1084 } catch (IllegalArgumentException success) {}
1085 }
1086 }
1087 }
1088
1089 void put(NavigableMap<Integer, Integer> map, int key) {
1090 if (map.put(key, 2 * key) == null)
1091 bs.set(key);
1092 }
1093
1094 void remove(NavigableMap<Integer, Integer> map, int key) {
1095 if (map.remove(key) != null)
1096 bs.clear(key);
1097 }
1098
1099 void bashSubMap(NavigableMap<Integer, Integer> map,
1100 int min, int max, boolean ascending) {
1101 check(map, min, max, ascending);
1102 check(map.descendingMap(), min, max, !ascending);
1103
1104 mutateSubMap(map, min, max);
1105 check(map, min, max, ascending);
1106 check(map.descendingMap(), min, max, !ascending);
1107
1108 // Recurse
1109 if (max - min < 2)
1110 return;
1111 int midPoint = (min + max) / 2;
1112
1113 // headMap - pick direction and endpoint inclusion randomly
1114 boolean incl = rnd.nextBoolean();
1115 NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
1116 if (ascending) {
1117 if (rnd.nextBoolean())
1118 bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
1119 else
1120 bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
1121 false);
1122 } else {
1123 if (rnd.nextBoolean())
1124 bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
1125 else
1126 bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
1127 true);
1128 }
1129
1130 // tailMap - pick direction and endpoint inclusion randomly
1131 incl = rnd.nextBoolean();
1132 NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
1133 if (ascending) {
1134 if (rnd.nextBoolean())
1135 bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
1136 else
1137 bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
1138 false);
1139 } else {
1140 if (rnd.nextBoolean()) {
1141 bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
1142 } else {
1143 bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
1144 true);
1145 }
1146 }
1147
1148 // subMap - pick direction and endpoint inclusion randomly
1149 int rangeSize = max - min + 1;
1150 int[] endpoints = new int[2];
1151 endpoints[0] = min + rnd.nextInt(rangeSize);
1152 endpoints[1] = min + rnd.nextInt(rangeSize);
1153 Arrays.sort(endpoints);
1154 boolean lowIncl = rnd.nextBoolean();
1155 boolean highIncl = rnd.nextBoolean();
1156 if (ascending) {
1157 NavigableMap<Integer,Integer> sm = map.subMap(
1158 endpoints[0], lowIncl, endpoints[1], highIncl);
1159 if (rnd.nextBoolean())
1160 bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
1161 endpoints[1] - (highIncl ? 0 : 1), true);
1162 else
1163 bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
1164 endpoints[1] - (highIncl ? 0 : 1), false);
1165 } else {
1166 NavigableMap<Integer,Integer> sm = map.subMap(
1167 endpoints[1], highIncl, endpoints[0], lowIncl);
1168 if (rnd.nextBoolean())
1169 bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
1170 endpoints[1] - (highIncl ? 0 : 1), false);
1171 else
1172 bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
1173 endpoints[1] - (highIncl ? 0 : 1), true);
1174 }
1175 }
1176
1177 /**
1178 * min and max are both inclusive. If max < min, interval is empty.
1179 */
1180 void check(NavigableMap<Integer, Integer> map,
1181 final int min, final int max, final boolean ascending) {
1182 class ReferenceSet {
1183 int lower(int key) {
1184 return ascending ? lowerAscending(key) : higherAscending(key);
1185 }
1186 int floor(int key) {
1187 return ascending ? floorAscending(key) : ceilingAscending(key);
1188 }
1189 int ceiling(int key) {
1190 return ascending ? ceilingAscending(key) : floorAscending(key);
1191 }
1192 int higher(int key) {
1193 return ascending ? higherAscending(key) : lowerAscending(key);
1194 }
1195 int first() {
1196 return ascending ? firstAscending() : lastAscending();
1197 }
1198 int last() {
1199 return ascending ? lastAscending() : firstAscending();
1200 }
1201 int lowerAscending(int key) {
1202 return floorAscending(key - 1);
1203 }
1204 int floorAscending(int key) {
1205 if (key < min)
1206 return -1;
1207 else if (key > max)
1208 key = max;
1209
1210 // BitSet should support this! Test would run much faster
1211 while (key >= min) {
1212 if (bs.get(key))
1213 return key;
1214 key--;
1215 }
1216 return -1;
1217 }
1218 int ceilingAscending(int key) {
1219 if (key < min)
1220 key = min;
1221 else if (key > max)
1222 return -1;
1223 int result = bs.nextSetBit(key);
1224 return result > max ? -1 : result;
1225 }
1226 int higherAscending(int key) {
1227 return ceilingAscending(key + 1);
1228 }
1229 private int firstAscending() {
1230 int result = ceilingAscending(min);
1231 return result > max ? -1 : result;
1232 }
1233 private int lastAscending() {
1234 int result = floorAscending(max);
1235 return result < min ? -1 : result;
1236 }
1237 }
1238 ReferenceSet rs = new ReferenceSet();
1239
1240 // Test contents using containsKey
1241 int size = 0;
1242 for (int i = min; i <= max; i++) {
1243 boolean bsContainsI = bs.get(i);
1244 assertEquals(bsContainsI, map.containsKey(i));
1245 if (bsContainsI)
1246 size++;
1247 }
1248 assertEquals(size, map.size());
1249
1250 // Test contents using contains keySet iterator
1251 int size2 = 0;
1252 int previousKey = -1;
1253 for (int key : map.keySet()) {
1254 assertTrue(bs.get(key));
1255 size2++;
1256 assertTrue(previousKey < 0 ||
1257 (ascending ? key - previousKey > 0 : key - previousKey < 0));
1258 previousKey = key;
1259 }
1260 assertEquals(size2, size);
1261
1262 // Test navigation ops
1263 for (int key = min - 1; key <= max + 1; key++) {
1264 assertEq(map.lowerKey(key), rs.lower(key));
1265 assertEq(map.floorKey(key), rs.floor(key));
1266 assertEq(map.higherKey(key), rs.higher(key));
1267 assertEq(map.ceilingKey(key), rs.ceiling(key));
1268 }
1269
1270 // Test extrema
1271 if (map.size() != 0) {
1272 assertEq(map.firstKey(), rs.first());
1273 assertEq(map.lastKey(), rs.last());
1274 } else {
1275 assertEq(rs.first(), -1);
1276 assertEq(rs.last(), -1);
1277 try {
1278 map.firstKey();
1279 shouldThrow();
1280 } catch (NoSuchElementException success) {}
1281 try {
1282 map.lastKey();
1283 shouldThrow();
1284 } catch (NoSuchElementException success) {}
1285 }
1286 }
1287
1288 static void assertEq(Integer i, int j) {
1289 if (i == null)
1290 assertEquals(j, -1);
1291 else
1292 assertEquals((int) i, j);
1293 }
1294
1295 static boolean eq(Integer i, int j) {
1296 return (i == null) ? j == -1 : i == j;
1297 }
1298
1299 }