ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.41
Committed: Wed Aug 23 05:33:00 2017 UTC (6 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.40: +13 -2 lines
Log Message:
8186171: HashMap: Entry.setValue may not work after Iterator.remove() called for previous entries

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