ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.24
Committed: Fri May 27 19:21:27 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.23: +1 -8 lines
Log Message:
indexOf => contains

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