ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.42
Committed: Sun Sep 29 20:40:48 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.41: +1 -2 lines
Log Message:
add MapTest.testConcurrentAccess

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