ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.12
Committed: Sat Nov 21 02:07:26 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.11: +81 -81 lines
Log Message:
untabify

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