ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.34
Committed: Wed Dec 31 21:45:16 2014 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.33: +2 -2 lines
Log Message:
whitespace

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 junit.textui.TestRunner.run(suite());
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 try {
698 ConcurrentSkipListMap c = map5();
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 try {
709 ConcurrentSkipListMap c = map5();
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 try {
720 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
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 try {
731 ConcurrentSkipListMap c = map5();
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 try {
742 ConcurrentSkipListMap c = map5();
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 try {
753 ConcurrentSkipListMap c = map5();
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 try {
764 ConcurrentSkipListMap c = map5();
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 try {
775 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
776 c.put("sadsdf", "asdads");
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 try {
787 ConcurrentSkipListMap c = new ConcurrentSkipListMap();
788 c.put("sadsdf", "asdads");
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 deserialized map equals original
805 */
806 public void testSerialization() throws Exception {
807 NavigableMap x = map5();
808 NavigableMap y = serialClone(x);
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 }
816
817 /**
818 * subMap returns map with keys in requested range
819 */
820 public void testSubMapContents() {
821 ConcurrentSkipListMap map = map5();
822 NavigableMap sm = map.subMap(two, true, four, false);
823 assertEquals(two, sm.firstKey());
824 assertEquals(three, sm.lastKey());
825 assertEquals(2, sm.size());
826 assertFalse(sm.containsKey(one));
827 assertTrue(sm.containsKey(two));
828 assertTrue(sm.containsKey(three));
829 assertFalse(sm.containsKey(four));
830 assertFalse(sm.containsKey(five));
831 Iterator i = sm.keySet().iterator();
832 Object k;
833 k = (Integer)(i.next());
834 assertEquals(two, k);
835 k = (Integer)(i.next());
836 assertEquals(three, k);
837 assertFalse(i.hasNext());
838 Iterator r = sm.descendingKeySet().iterator();
839 k = (Integer)(r.next());
840 assertEquals(three, k);
841 k = (Integer)(r.next());
842 assertEquals(two, k);
843 assertFalse(r.hasNext());
844
845 Iterator j = sm.keySet().iterator();
846 j.next();
847 j.remove();
848 assertFalse(map.containsKey(two));
849 assertEquals(4, map.size());
850 assertEquals(1, sm.size());
851 assertEquals(three, sm.firstKey());
852 assertEquals(three, sm.lastKey());
853 assertEquals("C", sm.remove(three));
854 assertTrue(sm.isEmpty());
855 assertEquals(3, map.size());
856 }
857
858 public void testSubMapContents2() {
859 ConcurrentSkipListMap map = map5();
860 NavigableMap sm = map.subMap(two, true, three, false);
861 assertEquals(1, sm.size());
862 assertEquals(two, sm.firstKey());
863 assertEquals(two, sm.lastKey());
864 assertFalse(sm.containsKey(one));
865 assertTrue(sm.containsKey(two));
866 assertFalse(sm.containsKey(three));
867 assertFalse(sm.containsKey(four));
868 assertFalse(sm.containsKey(five));
869 Iterator i = sm.keySet().iterator();
870 Object k;
871 k = (Integer)(i.next());
872 assertEquals(two, k);
873 assertFalse(i.hasNext());
874 Iterator r = sm.descendingKeySet().iterator();
875 k = (Integer)(r.next());
876 assertEquals(two, k);
877 assertFalse(r.hasNext());
878
879 Iterator j = sm.keySet().iterator();
880 j.next();
881 j.remove();
882 assertFalse(map.containsKey(two));
883 assertEquals(4, map.size());
884 assertEquals(0, sm.size());
885 assertTrue(sm.isEmpty());
886 assertSame(sm.remove(three), null);
887 assertEquals(4, map.size());
888 }
889
890 /**
891 * headMap returns map with keys in requested range
892 */
893 public void testHeadMapContents() {
894 ConcurrentSkipListMap map = map5();
895 NavigableMap sm = map.headMap(four, false);
896 assertTrue(sm.containsKey(one));
897 assertTrue(sm.containsKey(two));
898 assertTrue(sm.containsKey(three));
899 assertFalse(sm.containsKey(four));
900 assertFalse(sm.containsKey(five));
901 Iterator i = sm.keySet().iterator();
902 Object k;
903 k = (Integer)(i.next());
904 assertEquals(one, k);
905 k = (Integer)(i.next());
906 assertEquals(two, k);
907 k = (Integer)(i.next());
908 assertEquals(three, k);
909 assertFalse(i.hasNext());
910 sm.clear();
911 assertTrue(sm.isEmpty());
912 assertEquals(2, map.size());
913 assertEquals(four, map.firstKey());
914 }
915
916 /**
917 * tailMap returns map with keys in requested range
918 */
919 public void testTailMapContents() {
920 ConcurrentSkipListMap map = map5();
921 NavigableMap sm = map.tailMap(two, true);
922 assertFalse(sm.containsKey(one));
923 assertTrue(sm.containsKey(two));
924 assertTrue(sm.containsKey(three));
925 assertTrue(sm.containsKey(four));
926 assertTrue(sm.containsKey(five));
927 Iterator i = sm.keySet().iterator();
928 Object k;
929 k = (Integer)(i.next());
930 assertEquals(two, k);
931 k = (Integer)(i.next());
932 assertEquals(three, k);
933 k = (Integer)(i.next());
934 assertEquals(four, k);
935 k = (Integer)(i.next());
936 assertEquals(five, k);
937 assertFalse(i.hasNext());
938 Iterator r = sm.descendingKeySet().iterator();
939 k = (Integer)(r.next());
940 assertEquals(five, k);
941 k = (Integer)(r.next());
942 assertEquals(four, k);
943 k = (Integer)(r.next());
944 assertEquals(three, k);
945 k = (Integer)(r.next());
946 assertEquals(two, k);
947 assertFalse(r.hasNext());
948
949 Iterator ei = sm.entrySet().iterator();
950 Map.Entry e;
951 e = (Map.Entry)(ei.next());
952 assertEquals(two, e.getKey());
953 assertEquals("B", e.getValue());
954 e = (Map.Entry)(ei.next());
955 assertEquals(three, e.getKey());
956 assertEquals("C", e.getValue());
957 e = (Map.Entry)(ei.next());
958 assertEquals(four, e.getKey());
959 assertEquals("D", e.getValue());
960 e = (Map.Entry)(ei.next());
961 assertEquals(five, e.getKey());
962 assertEquals("E", e.getValue());
963 assertFalse(i.hasNext());
964
965 NavigableMap ssm = sm.tailMap(four, true);
966 assertEquals(four, ssm.firstKey());
967 assertEquals(five, ssm.lastKey());
968 assertEquals("D", ssm.remove(four));
969 assertEquals(1, ssm.size());
970 assertEquals(3, sm.size());
971 assertEquals(4, map.size());
972 }
973
974 Random rnd = new Random(666);
975 BitSet bs;
976
977 /**
978 * Submaps of submaps subdivide correctly
979 */
980 public void testRecursiveSubMaps() throws Exception {
981 int mapSize = expensiveTests ? 1000 : 100;
982 Class cl = ConcurrentSkipListMap.class;
983 NavigableMap<Integer, Integer> map = newMap(cl);
984 bs = new BitSet(mapSize);
985
986 populate(map, mapSize);
987 check(map, 0, mapSize - 1, true);
988 check(map.descendingMap(), 0, mapSize - 1, false);
989
990 mutateMap(map, 0, mapSize - 1);
991 check(map, 0, mapSize - 1, true);
992 check(map.descendingMap(), 0, mapSize - 1, false);
993
994 bashSubMap(map.subMap(0, true, mapSize, false),
995 0, mapSize - 1, true);
996 }
997
998 static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
999 NavigableMap<Integer, Integer> result =
1000 (NavigableMap<Integer, Integer>) cl.newInstance();
1001 assertEquals(0, result.size());
1002 assertFalse(result.keySet().iterator().hasNext());
1003 return result;
1004 }
1005
1006 void populate(NavigableMap<Integer, Integer> map, int limit) {
1007 for (int i = 0, n = 2 * limit / 3; i < n; i++) {
1008 int key = rnd.nextInt(limit);
1009 put(map, key);
1010 }
1011 }
1012
1013 void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
1014 int size = map.size();
1015 int rangeSize = max - min + 1;
1016
1017 // Remove a bunch of entries directly
1018 for (int i = 0, n = rangeSize / 2; i < n; i++) {
1019 remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
1020 }
1021
1022 // Remove a bunch of entries with iterator
1023 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
1024 if (rnd.nextBoolean()) {
1025 bs.clear(it.next());
1026 it.remove();
1027 }
1028 }
1029
1030 // Add entries till we're back to original size
1031 while (map.size() < size) {
1032 int key = min + rnd.nextInt(rangeSize);
1033 assertTrue(key >= min && key <= max);
1034 put(map, key);
1035 }
1036 }
1037
1038 void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
1039 int size = map.size();
1040 int rangeSize = max - min + 1;
1041
1042 // Remove a bunch of entries directly
1043 for (int i = 0, n = rangeSize / 2; i < n; i++) {
1044 remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
1045 }
1046
1047 // Remove a bunch of entries with iterator
1048 for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
1049 if (rnd.nextBoolean()) {
1050 bs.clear(it.next());
1051 it.remove();
1052 }
1053 }
1054
1055 // Add entries till we're back to original size
1056 while (map.size() < size) {
1057 int key = min - 5 + rnd.nextInt(rangeSize + 10);
1058 if (key >= min && key <= max) {
1059 put(map, key);
1060 } else {
1061 try {
1062 map.put(key, 2 * key);
1063 shouldThrow();
1064 } catch (IllegalArgumentException success) {}
1065 }
1066 }
1067 }
1068
1069 void put(NavigableMap<Integer, Integer> map, int key) {
1070 if (map.put(key, 2 * key) == null)
1071 bs.set(key);
1072 }
1073
1074 void remove(NavigableMap<Integer, Integer> map, int key) {
1075 if (map.remove(key) != null)
1076 bs.clear(key);
1077 }
1078
1079 void bashSubMap(NavigableMap<Integer, Integer> map,
1080 int min, int max, boolean ascending) {
1081 check(map, min, max, ascending);
1082 check(map.descendingMap(), min, max, !ascending);
1083
1084 mutateSubMap(map, min, max);
1085 check(map, min, max, ascending);
1086 check(map.descendingMap(), min, max, !ascending);
1087
1088 // Recurse
1089 if (max - min < 2)
1090 return;
1091 int midPoint = (min + max) / 2;
1092
1093 // headMap - pick direction and endpoint inclusion randomly
1094 boolean incl = rnd.nextBoolean();
1095 NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
1096 if (ascending) {
1097 if (rnd.nextBoolean())
1098 bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
1099 else
1100 bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
1101 false);
1102 } else {
1103 if (rnd.nextBoolean())
1104 bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
1105 else
1106 bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
1107 true);
1108 }
1109
1110 // tailMap - pick direction and endpoint inclusion randomly
1111 incl = rnd.nextBoolean();
1112 NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
1113 if (ascending) {
1114 if (rnd.nextBoolean())
1115 bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
1116 else
1117 bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
1118 false);
1119 } else {
1120 if (rnd.nextBoolean()) {
1121 bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
1122 } else {
1123 bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
1124 true);
1125 }
1126 }
1127
1128 // subMap - pick direction and endpoint inclusion randomly
1129 int rangeSize = max - min + 1;
1130 int[] endpoints = new int[2];
1131 endpoints[0] = min + rnd.nextInt(rangeSize);
1132 endpoints[1] = min + rnd.nextInt(rangeSize);
1133 Arrays.sort(endpoints);
1134 boolean lowIncl = rnd.nextBoolean();
1135 boolean highIncl = rnd.nextBoolean();
1136 if (ascending) {
1137 NavigableMap<Integer,Integer> sm = map.subMap(
1138 endpoints[0], lowIncl, endpoints[1], highIncl);
1139 if (rnd.nextBoolean())
1140 bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
1141 endpoints[1] - (highIncl ? 0 : 1), true);
1142 else
1143 bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
1144 endpoints[1] - (highIncl ? 0 : 1), false);
1145 } else {
1146 NavigableMap<Integer,Integer> sm = map.subMap(
1147 endpoints[1], highIncl, endpoints[0], lowIncl);
1148 if (rnd.nextBoolean())
1149 bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
1150 endpoints[1] - (highIncl ? 0 : 1), false);
1151 else
1152 bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
1153 endpoints[1] - (highIncl ? 0 : 1), true);
1154 }
1155 }
1156
1157 /**
1158 * min and max are both inclusive. If max < min, interval is empty.
1159 */
1160 void check(NavigableMap<Integer, Integer> map,
1161 final int min, final int max, final boolean ascending) {
1162 class ReferenceSet {
1163 int lower(int key) {
1164 return ascending ? lowerAscending(key) : higherAscending(key);
1165 }
1166 int floor(int key) {
1167 return ascending ? floorAscending(key) : ceilingAscending(key);
1168 }
1169 int ceiling(int key) {
1170 return ascending ? ceilingAscending(key) : floorAscending(key);
1171 }
1172 int higher(int key) {
1173 return ascending ? higherAscending(key) : lowerAscending(key);
1174 }
1175 int first() {
1176 return ascending ? firstAscending() : lastAscending();
1177 }
1178 int last() {
1179 return ascending ? lastAscending() : firstAscending();
1180 }
1181 int lowerAscending(int key) {
1182 return floorAscending(key - 1);
1183 }
1184 int floorAscending(int key) {
1185 if (key < min)
1186 return -1;
1187 else if (key > max)
1188 key = max;
1189
1190 // BitSet should support this! Test would run much faster
1191 while (key >= min) {
1192 if (bs.get(key))
1193 return key;
1194 key--;
1195 }
1196 return -1;
1197 }
1198 int ceilingAscending(int key) {
1199 if (key < min)
1200 key = min;
1201 else if (key > max)
1202 return -1;
1203 int result = bs.nextSetBit(key);
1204 return result > max ? -1 : result;
1205 }
1206 int higherAscending(int key) {
1207 return ceilingAscending(key + 1);
1208 }
1209 private int firstAscending() {
1210 int result = ceilingAscending(min);
1211 return result > max ? -1 : result;
1212 }
1213 private int lastAscending() {
1214 int result = floorAscending(max);
1215 return result < min ? -1 : result;
1216 }
1217 }
1218 ReferenceSet rs = new ReferenceSet();
1219
1220 // Test contents using containsKey
1221 int size = 0;
1222 for (int i = min; i <= max; i++) {
1223 boolean bsContainsI = bs.get(i);
1224 assertEquals(bsContainsI, map.containsKey(i));
1225 if (bsContainsI)
1226 size++;
1227 }
1228 assertEquals(size, map.size());
1229
1230 // Test contents using contains keySet iterator
1231 int size2 = 0;
1232 int previousKey = -1;
1233 for (int key : map.keySet()) {
1234 assertTrue(bs.get(key));
1235 size2++;
1236 assertTrue(previousKey < 0 ||
1237 (ascending ? key - previousKey > 0 : key - previousKey < 0));
1238 previousKey = key;
1239 }
1240 assertEquals(size2, size);
1241
1242 // Test navigation ops
1243 for (int key = min - 1; key <= max + 1; key++) {
1244 assertEq(map.lowerKey(key), rs.lower(key));
1245 assertEq(map.floorKey(key), rs.floor(key));
1246 assertEq(map.higherKey(key), rs.higher(key));
1247 assertEq(map.ceilingKey(key), rs.ceiling(key));
1248 }
1249
1250 // Test extrema
1251 if (map.size() != 0) {
1252 assertEq(map.firstKey(), rs.first());
1253 assertEq(map.lastKey(), rs.last());
1254 } else {
1255 assertEq(rs.first(), -1);
1256 assertEq(rs.last(), -1);
1257 try {
1258 map.firstKey();
1259 shouldThrow();
1260 } catch (NoSuchElementException success) {}
1261 try {
1262 map.lastKey();
1263 shouldThrow();
1264 } catch (NoSuchElementException success) {}
1265 }
1266 }
1267
1268 static void assertEq(Integer i, int j) {
1269 if (i == null)
1270 assertEquals(j, -1);
1271 else
1272 assertEquals((int) i, j);
1273 }
1274
1275 static boolean eq(Integer i, int j) {
1276 return i == null ? j == -1 : i == j;
1277 }
1278
1279 }