ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.6
Committed: Wed Apr 19 15:10:54 2006 UTC (18 years, 1 month ago) by dl
Branch: MAIN
Changes since 1.5: +323 -8 lines
Log Message:
Updated Navigable tests

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