ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.9
Committed: Mon Nov 2 20:28:31 2009 UTC (14 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.8: +9 -9 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.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 jsr166 1.9 junit.textui.TestRunner.run (suite());
15 dl 1.1 }
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 jsr166 1.9 private static ConcurrentSkipListMap map5() {
24 dl 1.1 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 jsr166 1.9 *
47 dl 1.1 */
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 dl 1.8 int count = 1;
173 dl 1.1 while (i.hasNext()) {
174     Integer k = (Integer)i.next();
175     assertTrue(last.compareTo(k) < 0);
176     last = k;
177 dl 1.8 ++count;
178 dl 1.1 }
179 dl 1.8 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 dl 1.1 }
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 dl 1.8 int count = 1;
211 dl 1.1 while (i.hasNext()) {
212     Integer k = (Integer)i.next();
213     assertTrue(last.compareTo(k) > 0);
214     last = k;
215 dl 1.8 ++count;
216 dl 1.1 }
217 dl 1.8 assertEquals(count, 5);
218 dl 1.1 }
219    
220 dl 1.8 /**
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 dl 1.4
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 dl 1.1 /**
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 jsr166 1.9 assertTrue(
280 dl 1.1 (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 dl 1.6 Set s = map.descendingMap().entrySet();
294 dl 1.1 assertEquals(5, s.size());
295     Iterator it = s.iterator();
296     while (it.hasNext()) {
297     Map.Entry e = (Map.Entry) it.next();
298 jsr166 1.9 assertTrue(
299 dl 1.1 (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 dl 1.6 Set s = map.descendingMap().entrySet();
327 dl 1.1 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 dl 1.5 /**
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 dl 1.1
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 jsr166 1.9 }
695 dl 1.1
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 dl 1.3 * 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 dl 1.1 * 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 dl 1.7 NavigableMap sm = map.subMap(two, true, four, false);
845 dl 1.1 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 jsr166 1.9
867 dl 1.1 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 dl 1.7 NavigableMap sm = map.subMap(two, true, three, false);
883 dl 1.1 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 jsr166 1.9
901 dl 1.1 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 dl 1.7 NavigableMap sm = map.headMap(four, false);
918 dl 1.1 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 dl 1.6 * tailMap returns map with keys in requested range
940 dl 1.1 */
941     public void testTailMapContents() {
942     ConcurrentSkipListMap map = map5();
943 dl 1.7 NavigableMap sm = map.tailMap(two, true);
944 dl 1.1 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 dl 1.7 NavigableMap ssm = sm.tailMap(four, true);
988 dl 1.1 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 dl 1.6
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 dl 1.7 bashSubMap(map.subMap(0, true, mapSize, false),
1017 dl 1.6 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 dl 1.7 NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
1124 dl 1.6 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 dl 1.7 NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
1141 dl 1.6 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 dl 1.7 NavigableMap<Integer,Integer> sm = map.subMap(
1166 dl 1.6 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 dl 1.7 NavigableMap<Integer,Integer> sm = map.subMap(
1175 dl 1.6 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 jsr166 1.9
1311 dl 1.1 }