ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentSkipListMapTest.java
Revision: 1.44
Committed: Wed Jan 27 01:57:24 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.43: +11 -11 lines
Log Message:
use diamond <> pervasively

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 dl 1.43 * Returns a new map from Items 1-5 to Strings "A"-"E".
43 dl 1.1 */
44 dl 1.43 private static ConcurrentSkipListMap<Item,String> map5() {
45 jsr166 1.44 ConcurrentSkipListMap<Item,String> 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 dl 1.43 mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
62 jsr166 1.12 map.clear();
63 dl 1.43 mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
71 jsr166 1.44 ConcurrentSkipListMap<Item,String> map2 = new ConcurrentSkipListMap<>(map);
72 dl 1.43 mustEqual(map, map2);
73 dl 1.1 }
74    
75     /**
76 jsr166 1.20 * Maps with same contents are equal
77 dl 1.1 */
78     public void testEquals() {
79 dl 1.43 ConcurrentSkipListMap<Item,String> map1 = map5();
80     ConcurrentSkipListMap<Item,String> map2 = map5();
81     mustEqual(map1, map2);
82     mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
112     mustEqual("A", map.get(one));
113 jsr166 1.44 ConcurrentSkipListMap<Item,String> empty = new ConcurrentSkipListMap<>();
114 dl 1.1 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 jsr166 1.44 ConcurrentSkipListMap<Item,String> empty = new ConcurrentSkipListMap<>();
122 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
132     mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
140     mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
148     Set<Item> s = map.keySet();
149 dl 1.1 Object[] ar = s.toArray();
150     assertTrue(s.containsAll(Arrays.asList(ar)));
151 dl 1.43 mustEqual(5, ar.length);
152     ar[0] = minusTen;
153 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
161     Set<Item> s = map.descendingKeySet();
162 dl 1.1 Object[] ar = s.toArray();
163 dl 1.43 mustEqual(5, ar.length);
164 dl 1.1 assertTrue(s.containsAll(Arrays.asList(ar)));
165 dl 1.43 ar[0] = minusTen;
166 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
174     Set<Item> s = map.keySet();
175     mustEqual(5, s.size());
176     mustContain(s, one);
177     mustContain(s, two);
178     mustContain(s, three);
179     mustContain(s, four);
180     mustContain(s, five);
181 dl 1.1 }
182    
183     /**
184 jsr166 1.20 * keySet is ordered
185 dl 1.1 */
186     public void testKeySetOrder() {
187 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
188     Set<Item> s = map.keySet();
189     Iterator<? extends Item> i = s.iterator();
190     Item last = i.next();
191     mustEqual(last, one);
192 dl 1.8 int count = 1;
193 dl 1.1 while (i.hasNext()) {
194 dl 1.43 Item k = i.next();
195 dl 1.1 assertTrue(last.compareTo(k) < 0);
196     last = k;
197 dl 1.8 ++count;
198 dl 1.1 }
199 dl 1.43 mustEqual(5, count);
200 dl 1.8 }
201    
202     /**
203     * descending iterator of key set is inverse ordered
204     */
205     public void testKeySetDescendingIteratorOrder() {
206 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
207     NavigableSet<Item> s = map.navigableKeySet();
208     Iterator<? extends Item> i = s.descendingIterator();
209     Item last = (Item)i.next();
210     mustEqual(last, five);
211 dl 1.8 int count = 1;
212     while (i.hasNext()) {
213 dl 1.43 Item k = (Item)i.next();
214 dl 1.8 assertTrue(last.compareTo(k) > 0);
215     last = k;
216     ++count;
217     }
218 dl 1.43 mustEqual(5, count);
219 dl 1.1 }
220    
221     /**
222 jsr166 1.20 * descendingKeySet is ordered
223 dl 1.1 */
224     public void testDescendingKeySetOrder() {
225 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
226     Set<Item> s = map.descendingKeySet();
227     Iterator<? extends Item> i = s.iterator();
228     Item last = (Item)i.next();
229     mustEqual(last, five);
230 dl 1.8 int count = 1;
231 dl 1.1 while (i.hasNext()) {
232 dl 1.43 Item k = (Item)i.next();
233 dl 1.1 assertTrue(last.compareTo(k) > 0);
234     last = k;
235 dl 1.8 ++count;
236 dl 1.1 }
237 dl 1.43 mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
245     NavigableSet<Item> s = map.descendingKeySet();
246     Iterator<? extends Item> i = s.descendingIterator();
247     Item last = (Item)i.next();
248     mustEqual(last, one);
249 dl 1.8 int count = 1;
250     while (i.hasNext()) {
251 dl 1.43 Item k = (Item)i.next();
252 dl 1.8 assertTrue(last.compareTo(k) < 0);
253     last = k;
254     ++count;
255     }
256 dl 1.43 mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
264     Collection<String> v = map.values();
265     String[] ar = v.toArray(new String[0]);
266 jsr166 1.44 ArrayList<String> s = new ArrayList<>(Arrays.asList(ar));
267 dl 1.43 mustEqual(5, ar.length);
268 jsr166 1.12 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
280     Collection<String> s = map.values();
281     mustEqual(5, s.size());
282 jsr166 1.12 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
294     Set<Map.Entry<Item,String>> s = map.entrySet();
295     mustEqual(5, s.size());
296     Iterator<Map.Entry<Item,String>> it = s.iterator();
297 dl 1.1 while (it.hasNext()) {
298 dl 1.43 Map.Entry<Item,String> e = 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
313     Set<Map.Entry<Item,String>> s = map.descendingMap().entrySet();
314     mustEqual(5, s.size());
315     Iterator<Map.Entry<Item,String>> it = s.iterator();
316 dl 1.1 while (it.hasNext()) {
317 dl 1.43 Map.Entry<Item,String> e = 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
332     Set<Map.Entry<Item,String>> s = map.entrySet();
333 dl 1.1 Object[] ar = s.toArray();
334 dl 1.43 mustEqual(5, ar.length);
335 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
346     Set<Map.Entry<Item,String>> s = map.descendingMap().entrySet();
347 dl 1.1 Object[] ar = s.toArray();
348 dl 1.43 mustEqual(5, ar.length);
349 dl 1.1 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 jsr166 1.44 ConcurrentSkipListMap<Item,String> p = new ConcurrentSkipListMap<>();
360 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
361     p.putAll(map);
362     mustEqual(5, p.size());
363     assertTrue(p.containsKey(one));
364     assertTrue(p.containsKey(two));
365     assertTrue(p.containsKey(three));
366     assertTrue(p.containsKey(four));
367     assertTrue(p.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 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
384     mustEqual("A", map.putIfAbsent(one, "Z"));
385 dl 1.1 }
386    
387     /**
388 jsr166 1.20 * replace fails when the given key is not present
389 dl 1.1 */
390     public void testReplace() {
391 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
401 dl 1.1 assertNotNull(map.replace(one, "Z"));
402 dl 1.43 mustEqual("Z", map.get(one));
403 dl 1.1 }
404    
405     /**
406     * replace value fails when the given key not mapped to expected value
407     */
408     public void testReplaceValue() {
409 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
410     mustEqual("A", map.get(one));
411 jsr166 1.12 assertFalse(map.replace(one, "Z", "Z"));
412 dl 1.43 mustEqual("A", map.get(one));
413 dl 1.1 }
414    
415     /**
416     * replace value succeeds when the given key mapped to expected value
417     */
418     public void testReplaceValue2() {
419 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
420     mustEqual("A", map.get(one));
421 jsr166 1.12 assertTrue(map.replace(one, "A", "Z"));
422 dl 1.43 mustEqual("Z", map.get(one));
423 dl 1.1 }
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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
430 jsr166 1.12 map.remove(five);
431 dl 1.43 mustEqual(4, map.size());
432 jsr166 1.12 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
440 jsr166 1.12 assertTrue(map.containsKey(five));
441 dl 1.43 mustEqual("E", map.get(five));
442 jsr166 1.12 map.remove(five, "E");
443 dl 1.43 mustEqual(4, map.size());
444 jsr166 1.12 assertFalse(map.containsKey(five));
445     map.remove(four, "A");
446 dl 1.43 mustEqual(4, map.size());
447 jsr166 1.12 assertTrue(map.containsKey(four));
448 dl 1.1 }
449    
450     /**
451     * lowerEntry returns preceding entry.
452     */
453     public void testLowerEntry() {
454 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
455     Map.Entry<Item,String> e1 = map.lowerEntry(three);
456     mustEqual(two, e1.getKey());
457 dl 1.1
458 dl 1.43 Map.Entry<Item,String> e2 = map.lowerEntry(six);
459     mustEqual(five, e2.getKey());
460 dl 1.1
461 dl 1.43 Map.Entry<Item,String> e3 = map.lowerEntry(one);
462 dl 1.1 assertNull(e3);
463    
464 dl 1.43 Map.Entry<Item,String> e4 = map.lowerEntry(zero);
465 dl 1.1 assertNull(e4);
466     }
467    
468     /**
469     * higherEntry returns next entry.
470     */
471     public void testHigherEntry() {
472 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
473     Map.Entry<Item,String> e1 = map.higherEntry(three);
474     mustEqual(four, e1.getKey());
475 dl 1.1
476 dl 1.43 Map.Entry<Item,String> e2 = map.higherEntry(zero);
477     mustEqual(one, e2.getKey());
478 dl 1.1
479 dl 1.43 Map.Entry<Item,String> e3 = map.higherEntry(five);
480 dl 1.1 assertNull(e3);
481    
482 dl 1.43 Map.Entry<Item,String> e4 = map.higherEntry(six);
483 dl 1.1 assertNull(e4);
484     }
485    
486     /**
487     * floorEntry returns preceding entry.
488     */
489     public void testFloorEntry() {
490 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
491     Map.Entry<Item,String> e1 = map.floorEntry(three);
492     mustEqual(three, e1.getKey());
493 dl 1.1
494 dl 1.43 Map.Entry<Item,String> e2 = map.floorEntry(six);
495     mustEqual(five, e2.getKey());
496 dl 1.1
497 dl 1.43 Map.Entry<Item,String> e3 = map.floorEntry(one);
498     mustEqual(one, e3.getKey());
499 dl 1.1
500 dl 1.43 Map.Entry<Item,String> e4 = map.floorEntry(zero);
501 dl 1.1 assertNull(e4);
502     }
503    
504     /**
505     * ceilingEntry returns next entry.
506     */
507     public void testCeilingEntry() {
508 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
509     Map.Entry<Item,String> e1 = map.ceilingEntry(three);
510     mustEqual(three, e1.getKey());
511 dl 1.1
512 dl 1.43 Map.Entry<Item,String> e2 = map.ceilingEntry(zero);
513     mustEqual(one, e2.getKey());
514 dl 1.1
515 dl 1.43 Map.Entry<Item,String> e3 = map.ceilingEntry(five);
516     mustEqual(five, e3.getKey());
517 dl 1.1
518 dl 1.43 Map.Entry<Item,String> e4 = map.ceilingEntry(six);
519 dl 1.1 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.43 ConcurrentSkipListMap<Item,String> map = map5();
528     Map.Entry<Item,String> e = map.lowerEntry(three);
529     mustEqual(two, e.getKey());
530 dl 1.5 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 dl 1.43 mustEqual(one, e.getKey());
536 dl 1.5 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 dl 1.43 mustEqual(one, e.getKey());
542 dl 1.5 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 dl 1.43 mustEqual(five, e.getKey());
548 dl 1.5 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 dl 1.43 ConcurrentSkipListMap<Item,String> q = map5();
559 dl 1.1 Object e1 = q.lowerKey(three);
560 dl 1.43 mustEqual(two, e1);
561 dl 1.1
562     Object e2 = q.lowerKey(six);
563 dl 1.43 mustEqual(five, e2);
564 dl 1.1
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 dl 1.43 ConcurrentSkipListMap<Item,String> q = map5();
577 dl 1.1 Object e1 = q.higherKey(three);
578 dl 1.43 mustEqual(four, e1);
579 dl 1.1
580     Object e2 = q.higherKey(zero);
581 dl 1.43 mustEqual(one, e2);
582 dl 1.1
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 dl 1.43 ConcurrentSkipListMap<Item,String> q = map5();
595 dl 1.1 Object e1 = q.floorKey(three);
596 dl 1.43 mustEqual(three, e1);
597 dl 1.1
598     Object e2 = q.floorKey(six);
599 dl 1.43 mustEqual(five, e2);
600 dl 1.1
601     Object e3 = q.floorKey(one);
602 dl 1.43 mustEqual(one, e3);
603 dl 1.1
604     Object e4 = q.floorKey(zero);
605     assertNull(e4);
606     }
607    
608     /**
609     * ceilingKey returns next element
610     */
611     public void testCeilingKey() {
612 dl 1.43 ConcurrentSkipListMap<Item,String> q = map5();
613 dl 1.1 Object e1 = q.ceilingKey(three);
614 dl 1.43 mustEqual(three, e1);
615 dl 1.1
616     Object e2 = q.ceilingKey(zero);
617 dl 1.43 mustEqual(one, e2);
618 dl 1.1
619     Object e3 = q.ceilingKey(five);
620 dl 1.43 mustEqual(five, e3);
621 dl 1.1
622     Object e4 = q.ceilingKey(six);
623     assertNull(e4);
624     }
625    
626     /**
627     * pollFirstEntry returns entries in order
628     */
629     public void testPollFirstEntry() {
630 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
631     Map.Entry<Item,String> e = map.pollFirstEntry();
632     mustEqual(one, e.getKey());
633     mustEqual("A", e.getValue());
634 dl 1.1 e = map.pollFirstEntry();
635 dl 1.43 mustEqual(two, e.getKey());
636 dl 1.1 map.put(one, "A");
637     e = map.pollFirstEntry();
638 dl 1.43 mustEqual(one, e.getKey());
639     mustEqual("A", e.getValue());
640 dl 1.1 e = map.pollFirstEntry();
641 dl 1.43 mustEqual(three, e.getKey());
642 dl 1.1 map.remove(four);
643     e = map.pollFirstEntry();
644 dl 1.43 mustEqual(five, e.getKey());
645 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
658     Map.Entry<Item,String> e = map.pollLastEntry();
659     mustEqual(five, e.getKey());
660     mustEqual("E", e.getValue());
661 dl 1.1 e = map.pollLastEntry();
662 dl 1.43 mustEqual(four, e.getKey());
663 dl 1.1 map.put(five, "E");
664     e = map.pollLastEntry();
665 dl 1.43 mustEqual(five, e.getKey());
666     mustEqual("E", e.getValue());
667 dl 1.1 e = map.pollLastEntry();
668 dl 1.43 mustEqual(three, e.getKey());
669 dl 1.1 map.remove(two);
670     e = map.pollLastEntry();
671 dl 1.43 mustEqual(one, e.getKey());
672 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
685 jsr166 1.44 ConcurrentSkipListMap<Item,String> empty = new ConcurrentSkipListMap<>();
686 dl 1.43 mustEqual(0, empty.size());
687     mustEqual(5, map.size());
688 dl 1.1 }
689    
690     /**
691     * toString contains toString of elements
692     */
693     public void testToString() {
694 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
695 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> 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.44 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> 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 dl 1.43 ConcurrentSkipListMap<Item,String> c = map5();
763 dl 1.1 try {
764 dl 1.43 c.replace(null, "A");
765 dl 1.1 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 dl 1.43 ConcurrentSkipListMap<Item,String> c = map5();
774 dl 1.1 try {
775 dl 1.43 c.replace(null, "A", "B");
776 dl 1.1 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.44 ConcurrentSkipListMap<Item,String> c = new ConcurrentSkipListMap<>();
785 dl 1.43 c.put(zero, "A");
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.44 ConcurrentSkipListMap<Item,String> c = new ConcurrentSkipListMap<>();
797 dl 1.43 c.put(zero, "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.44 ConcurrentSkipListMap<Item,String> c = new ConcurrentSkipListMap<>();
809 dl 1.43 c.put(zero, "asdads");
810 jsr166 1.14 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 dl 1.43 ConcurrentSkipListMap<Item,String> x = map5();
818     ConcurrentSkipListMap<Item,String> y = x.clone();
819 jsr166 1.39
820     assertNotSame(x, y);
821 dl 1.43 mustEqual(x.size(), y.size());
822     mustEqual(x.toString(), y.toString());
823     mustEqual(x, y);
824     mustEqual(y, x);
825 jsr166 1.39 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 dl 1.43 NavigableMap<Item,String> x = map5();
835     NavigableMap<Item,String> y = serialClone(x);
836 dl 1.1
837 jsr166 1.32 assertNotSame(x, y);
838 dl 1.43 mustEqual(x.size(), y.size());
839     mustEqual(x.toString(), y.toString());
840     mustEqual(x, y);
841     mustEqual(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 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
852     NavigableMap<Item,String> sm = map.subMap(two, true, four, false);
853     mustEqual(two, sm.firstKey());
854     mustEqual(three, sm.lastKey());
855     mustEqual(2, sm.size());
856 dl 1.1 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 dl 1.43 Iterator<? extends Item> i = sm.keySet().iterator();
862     Item k;
863     k = (Item)(i.next());
864     mustEqual(two, k);
865     k = (Item)(i.next());
866     mustEqual(three, k);
867 dl 1.1 assertFalse(i.hasNext());
868 dl 1.43 Iterator<? extends Item> r = sm.descendingKeySet().iterator();
869     k = (Item)(r.next());
870     mustEqual(three, k);
871     k = (Item)(r.next());
872     mustEqual(two, k);
873 dl 1.1 assertFalse(r.hasNext());
874 jsr166 1.9
875 dl 1.43 Iterator<? extends Item> j = sm.keySet().iterator();
876 dl 1.1 j.next();
877     j.remove();
878     assertFalse(map.containsKey(two));
879 dl 1.43 mustEqual(4, map.size());
880     mustEqual(1, sm.size());
881     mustEqual(three, sm.firstKey());
882     mustEqual(three, sm.lastKey());
883     mustEqual("C", sm.remove(three));
884 dl 1.1 assertTrue(sm.isEmpty());
885 dl 1.43 mustEqual(3, map.size());
886 dl 1.1 }
887    
888     public void testSubMapContents2() {
889 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
890     NavigableMap<Item,String> sm = map.subMap(two, true, three, false);
891     mustEqual(1, sm.size());
892     mustEqual(two, sm.firstKey());
893     mustEqual(two, sm.lastKey());
894 dl 1.1 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 dl 1.43 Iterator<? extends Item> i = sm.keySet().iterator();
900     Item k;
901     k = (Item)(i.next());
902     mustEqual(two, k);
903 dl 1.1 assertFalse(i.hasNext());
904 dl 1.43 Iterator<? extends Item> r = sm.descendingKeySet().iterator();
905     k = (Item)(r.next());
906     mustEqual(two, k);
907 dl 1.1 assertFalse(r.hasNext());
908 jsr166 1.9
909 dl 1.43 Iterator<? extends Item> j = sm.keySet().iterator();
910 dl 1.1 j.next();
911     j.remove();
912     assertFalse(map.containsKey(two));
913 dl 1.43 mustEqual(4, map.size());
914     mustEqual(0, sm.size());
915 dl 1.1 assertTrue(sm.isEmpty());
916 jsr166 1.15 assertSame(sm.remove(three), null);
917 dl 1.43 mustEqual(4, map.size());
918 dl 1.1 }
919    
920     /**
921     * headMap returns map with keys in requested range
922     */
923     public void testHeadMapContents() {
924 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
925     NavigableMap<Item,String> 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 dl 1.43 Iterator<? extends Item> i = sm.keySet().iterator();
932     Item k;
933     k = (Item)(i.next());
934     mustEqual(one, k);
935     k = (Item)(i.next());
936     mustEqual(two, k);
937     k = (Item)(i.next());
938     mustEqual(three, k);
939 dl 1.1 assertFalse(i.hasNext());
940     sm.clear();
941     assertTrue(sm.isEmpty());
942 dl 1.43 mustEqual(2, map.size());
943     mustEqual(four, map.firstKey());
944 dl 1.1 }
945    
946     /**
947 dl 1.6 * tailMap returns map with keys in requested range
948 dl 1.1 */
949     public void testTailMapContents() {
950 dl 1.43 ConcurrentSkipListMap<Item,String> map = map5();
951     NavigableMap<Item,String> 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 dl 1.43 Iterator<? extends Item> i = sm.keySet().iterator();
958     Item k = i.next();
959     mustEqual(two, k);
960     k = i.next();
961     mustEqual(three, k);
962     k = i.next();
963     mustEqual(four, k);
964     k = i.next();
965     mustEqual(five, k);
966 dl 1.1 assertFalse(i.hasNext());
967 dl 1.43 Iterator<Item> r = sm.descendingKeySet().iterator();
968     k = r.next();
969     mustEqual(five, k);
970     k = r.next();
971     mustEqual(four, k);
972     k = r.next();
973     mustEqual(three, k);
974     k = r.next();
975     mustEqual(two, k);
976 dl 1.1 assertFalse(r.hasNext());
977    
978 dl 1.43 Iterator<Map.Entry<Item,String>> ei = sm.entrySet().iterator();
979     Map.Entry<Item,String> e;
980     e = (ei.next());
981     mustEqual(two, e.getKey());
982     mustEqual("B", e.getValue());
983     e = (ei.next());
984     mustEqual(three, e.getKey());
985     mustEqual("C", e.getValue());
986     e = (ei.next());
987     mustEqual(four, e.getKey());
988     mustEqual("D", e.getValue());
989     e = (ei.next());
990     mustEqual(five, e.getKey());
991     mustEqual("E", e.getValue());
992 dl 1.1 assertFalse(i.hasNext());
993    
994 dl 1.43 NavigableMap<Item,String> ssm = sm.tailMap(four, true);
995     mustEqual(four, ssm.firstKey());
996     mustEqual(five, ssm.lastKey());
997     mustEqual("D", ssm.remove(four));
998     mustEqual(1, ssm.size());
999     mustEqual(3, sm.size());
1000     mustEqual(4, map.size());
1001 dl 1.1 }
1002 dl 1.6
1003     Random rnd = new Random(666);
1004     BitSet bs;
1005    
1006     /**
1007     * Submaps of submaps subdivide correctly
1008     */
1009 jsr166 1.14 public void testRecursiveSubMaps() throws Exception {
1010 jsr166 1.21 int mapSize = expensiveTests ? 1000 : 100;
1011 dl 1.43 Class<?> cl = ConcurrentSkipListMap.class;
1012     NavigableMap<Item, Item> map = newMap(cl);
1013 dl 1.6 bs = new BitSet(mapSize);
1014    
1015     populate(map, mapSize);
1016     check(map, 0, mapSize - 1, true);
1017     check(map.descendingMap(), 0, mapSize - 1, false);
1018    
1019     mutateMap(map, 0, mapSize - 1);
1020     check(map, 0, mapSize - 1, true);
1021     check(map.descendingMap(), 0, mapSize - 1, false);
1022    
1023 dl 1.43 bashSubMap(map.subMap(zero, true, itemFor(mapSize), false),
1024 dl 1.6 0, mapSize - 1, true);
1025     }
1026    
1027 dl 1.43 static NavigableMap<Item, Item> newMap(Class<?> cl) throws Exception {
1028     @SuppressWarnings("unchecked")
1029     NavigableMap<Item, Item> result =
1030     (NavigableMap<Item, Item>) cl.getConstructor().newInstance();
1031     mustEqual(0, result.size());
1032 dl 1.6 assertFalse(result.keySet().iterator().hasNext());
1033     return result;
1034     }
1035    
1036 dl 1.43 void populate(NavigableMap<Item, Item> map, int limit) {
1037 dl 1.6 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 dl 1.43 void mutateMap(NavigableMap<Item, Item> map, int min, int max) {
1044 dl 1.6 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 dl 1.43 for (Iterator<Item> it = map.keySet().iterator(); it.hasNext(); ) {
1054 dl 1.6 if (rnd.nextBoolean()) {
1055 dl 1.43 bs.clear(it.next().value);
1056 dl 1.6 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 dl 1.43 void mutateSubMap(NavigableMap<Item, Item> map, int min, int max) {
1069 dl 1.6 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 dl 1.43 for (Iterator<Item> it = map.keySet().iterator(); it.hasNext(); ) {
1079 dl 1.6 if (rnd.nextBoolean()) {
1080 dl 1.43 bs.clear(it.next().value);
1081 dl 1.6 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 dl 1.43 map.put(itemFor(key), itemFor(2 * key));
1093 jsr166 1.14 shouldThrow();
1094     } catch (IllegalArgumentException success) {}
1095 dl 1.6 }
1096     }
1097     }
1098    
1099 dl 1.43 void put(NavigableMap<Item, Item> map, int key) {
1100     if (map.put(itemFor(key), itemFor(2 * key)) == null)
1101 dl 1.6 bs.set(key);
1102     }
1103    
1104 dl 1.43 void remove(NavigableMap<Item, Item> map, int key) {
1105     if (map.remove(itemFor(key)) != null)
1106 dl 1.6 bs.clear(key);
1107     }
1108    
1109 dl 1.43 void bashSubMap(NavigableMap<Item, Item> map,
1110 dl 1.6 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.43 NavigableMap<Item,Item> hm = map.headMap(itemFor(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.43 NavigableMap<Item,Item> tm = map.tailMap(itemFor(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.43 NavigableMap<Item,Item> sm = map.subMap(
1168     itemFor(endpoints[0]), lowIncl, itemFor(endpoints[1]), highIncl);
1169 dl 1.6 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.43 NavigableMap<Item,Item> sm = map.subMap(
1177     itemFor(endpoints[1]), highIncl, itemFor(endpoints[0]), lowIncl);
1178 dl 1.6 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 dl 1.43 void check(NavigableMap<Item, Item> map,
1191 dl 1.6 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 dl 1.43 mustEqual(bsContainsI, map.containsKey(itemFor(i)));
1255 dl 1.6 if (bsContainsI)
1256     size++;
1257     }
1258 dl 1.43 mustEqual(size, map.size());
1259 dl 1.6
1260     // Test contents using contains keySet iterator
1261     int size2 = 0;
1262     int previousKey = -1;
1263 dl 1.43 for (Item key : map.keySet()) {
1264     assertTrue(bs.get(key.value));
1265 dl 1.6 size2++;
1266     assertTrue(previousKey < 0 ||
1267 dl 1.43 (ascending ? key.value - previousKey > 0 : key.value - previousKey < 0));
1268     previousKey = key.value;
1269 dl 1.6 }
1270 dl 1.43 mustEqual(size2, size);
1271 dl 1.6
1272     // Test navigation ops
1273     for (int key = min - 1; key <= max + 1; key++) {
1274 dl 1.43 Item k = itemFor(key);
1275     assertEq(map.lowerKey(k), rs.lower(key));
1276     assertEq(map.floorKey(k), rs.floor(key));
1277     assertEq(map.higherKey(k), rs.higher(key));
1278     assertEq(map.ceilingKey(k), rs.ceiling(key));
1279 dl 1.6 }
1280    
1281     // Test extrema
1282     if (map.size() != 0) {
1283     assertEq(map.firstKey(), rs.first());
1284     assertEq(map.lastKey(), rs.last());
1285     } else {
1286 dl 1.43 mustEqual(rs.first(), -1);
1287     mustEqual(rs.last(), -1);
1288 dl 1.6 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 dl 1.43 static void assertEq(Item i, int j) {
1300 dl 1.6 if (i == null)
1301 dl 1.43 mustEqual(j, -1);
1302 dl 1.6 else
1303 dl 1.43 mustEqual(i, j);
1304 dl 1.6 }
1305    
1306 dl 1.43 static boolean eq(Item i, int j) {
1307     return (i == null) ? j == -1 : i.value == j;
1308 dl 1.6 }
1309 jsr166 1.9
1310 dl 1.1 }