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/publicdomain/zero/1.0/
5  */
6 
7 package jsr166;
8 
9 import static java.util.Spliterator.CONCURRENT;
10 import static java.util.Spliterator.DISTINCT;
11 import static java.util.Spliterator.NONNULL;
12 
13 import java.util.AbstractMap;
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.Iterator;
18 import java.util.Map;
19 import java.util.NoSuchElementException;
20 import java.util.Set;
21 import java.util.Spliterator;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.atomic.LongAdder;
24 import java.util.function.BiFunction;
25 
26 import junit.framework.Test;
27 import junit.framework.TestSuite;
28 
29 public class ConcurrentHashMap8Test extends JSR166TestCase {
30     // android-note: Removed because the CTS runner does a bad job of
31     // retrying tests that have suite() declarations.
32     //
33     // public static void main(String[] args) {
34     //     main(suite(), args);
35     // }
36     // public static Test suite() {
37     //     return new TestSuite(ConcurrentHashMap8Test.class);
38     // }
39 
40     /**
41      * Returns a new map from Integers 1-5 to Strings "A"-"E".
42      */
map5()43     private static ConcurrentHashMap map5() {
44         ConcurrentHashMap map = new ConcurrentHashMap(5);
45         assertTrue(map.isEmpty());
46         map.put(one, "A");
47         map.put(two, "B");
48         map.put(three, "C");
49         map.put(four, "D");
50         map.put(five, "E");
51         assertFalse(map.isEmpty());
52         assertEquals(5, map.size());
53         return map;
54     }
55 
56     /**
57      * getOrDefault returns value if present, else default
58      */
testGetOrDefault()59     public void testGetOrDefault() {
60         ConcurrentHashMap map = map5();
61         assertEquals(map.getOrDefault(one, "Z"), "A");
62         assertEquals(map.getOrDefault(six, "Z"), "Z");
63     }
64 
65     /**
66      * computeIfAbsent adds when the given key is not present
67      */
testComputeIfAbsent()68     public void testComputeIfAbsent() {
69         ConcurrentHashMap map = map5();
70         map.computeIfAbsent(six, (x) -> "Z");
71         assertTrue(map.containsKey(six));
72     }
73 
74     /**
75      * computeIfAbsent does not replace if the key is already present
76      */
testComputeIfAbsent2()77     public void testComputeIfAbsent2() {
78         ConcurrentHashMap map = map5();
79         assertEquals("A", map.computeIfAbsent(one, (x) -> "Z"));
80     }
81 
82     /**
83      * computeIfAbsent does not add if function returns null
84      */
testComputeIfAbsent3()85     public void testComputeIfAbsent3() {
86         ConcurrentHashMap map = map5();
87         map.computeIfAbsent(six, (x) -> null);
88         assertFalse(map.containsKey(six));
89     }
90 
91     /**
92      * computeIfPresent does not replace if the key is already present
93      */
testComputeIfPresent()94     public void testComputeIfPresent() {
95         ConcurrentHashMap map = map5();
96         map.computeIfPresent(six, (x, y) -> "Z");
97         assertFalse(map.containsKey(six));
98     }
99 
100     /**
101      * computeIfPresent adds when the given key is not present
102      */
testComputeIfPresent2()103     public void testComputeIfPresent2() {
104         ConcurrentHashMap map = map5();
105         assertEquals("Z", map.computeIfPresent(one, (x, y) -> "Z"));
106     }
107 
108     /**
109      * compute does not replace if the function returns null
110      */
testCompute()111     public void testCompute() {
112         ConcurrentHashMap map = map5();
113         map.compute(six, (x, y) -> null);
114         assertFalse(map.containsKey(six));
115     }
116 
117     /**
118      * compute adds when the given key is not present
119      */
testCompute2()120     public void testCompute2() {
121         ConcurrentHashMap map = map5();
122         assertEquals("Z", map.compute(six, (x, y) -> "Z"));
123     }
124 
125     /**
126      * compute replaces when the given key is present
127      */
testCompute3()128     public void testCompute3() {
129         ConcurrentHashMap map = map5();
130         assertEquals("Z", map.compute(one, (x, y) -> "Z"));
131     }
132 
133     /**
134      * compute removes when the given key is present and function returns null
135      */
testCompute4()136     public void testCompute4() {
137         ConcurrentHashMap map = map5();
138         map.compute(one, (x, y) -> null);
139         assertFalse(map.containsKey(one));
140     }
141 
142     /**
143      * merge adds when the given key is not present
144      */
testMerge1()145     public void testMerge1() {
146         ConcurrentHashMap map = map5();
147         assertEquals("Y", map.merge(six, "Y", (x, y) -> "Z"));
148     }
149 
150     /**
151      * merge replaces when the given key is present
152      */
testMerge2()153     public void testMerge2() {
154         ConcurrentHashMap map = map5();
155         assertEquals("Z", map.merge(one, "Y", (x, y) -> "Z"));
156     }
157 
158     /**
159      * merge removes when the given key is present and function returns null
160      */
testMerge3()161     public void testMerge3() {
162         ConcurrentHashMap map = map5();
163         map.merge(one, "Y", (x, y) -> null);
164         assertFalse(map.containsKey(one));
165     }
166 
populatedSet(int n)167     static Set<Integer> populatedSet(int n) {
168         Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
169         assertTrue(a.isEmpty());
170         for (int i = 0; i < n; i++)
171             assertTrue(a.add(i));
172         assertEquals(n == 0, a.isEmpty());
173         assertEquals(n, a.size());
174         return a;
175     }
176 
populatedSet(Integer[] elements)177     static Set populatedSet(Integer[] elements) {
178         Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
179         assertTrue(a.isEmpty());
180         for (int i = 0; i < elements.length; i++)
181             assertTrue(a.add(elements[i]));
182         assertFalse(a.isEmpty());
183         assertEquals(elements.length, a.size());
184         return a;
185     }
186 
187     /**
188      * replaceAll replaces all matching values.
189      */
testReplaceAll()190     public void testReplaceAll() {
191         ConcurrentHashMap<Integer, String> map = map5();
192         map.replaceAll((x, y) -> { return x > 3 ? "Z" : y; });
193         assertEquals("A", map.get(one));
194         assertEquals("B", map.get(two));
195         assertEquals("C", map.get(three));
196         assertEquals("Z", map.get(four));
197         assertEquals("Z", map.get(five));
198     }
199 
200     /**
201      * Default-constructed set is empty
202      */
testNewKeySet()203     public void testNewKeySet() {
204         Set a = ConcurrentHashMap.newKeySet();
205         assertTrue(a.isEmpty());
206     }
207 
208     /**
209      * keySet.add adds the key with the established value to the map;
210      * remove removes it.
211      */
testKeySetAddRemove()212     public void testKeySetAddRemove() {
213         ConcurrentHashMap map = map5();
214         Set set1 = map.keySet();
215         Set set2 = map.keySet(true);
216         set2.add(six);
217         assertTrue(((ConcurrentHashMap.KeySetView)set2).getMap() == map);
218         assertTrue(((ConcurrentHashMap.KeySetView)set1).getMap() == map);
219         assertEquals(set2.size(), map.size());
220         assertEquals(set1.size(), map.size());
221         assertTrue((Boolean)map.get(six));
222         assertTrue(set1.contains(six));
223         assertTrue(set2.contains(six));
224         set2.remove(six);
225         assertNull(map.get(six));
226         assertFalse(set1.contains(six));
227         assertFalse(set2.contains(six));
228     }
229 
230     /**
231      * keySet.addAll adds each element from the given collection
232      */
testAddAll()233     public void testAddAll() {
234         Set full = populatedSet(3);
235         assertTrue(full.addAll(Arrays.asList(three, four, five)));
236         assertEquals(6, full.size());
237         assertFalse(full.addAll(Arrays.asList(three, four, five)));
238         assertEquals(6, full.size());
239     }
240 
241     /**
242      * keySet.addAll adds each element from the given collection that did not
243      * already exist in the set
244      */
testAddAll2()245     public void testAddAll2() {
246         Set full = populatedSet(3);
247         // "one" is duplicate and will not be added
248         assertTrue(full.addAll(Arrays.asList(three, four, one)));
249         assertEquals(5, full.size());
250         assertFalse(full.addAll(Arrays.asList(three, four, one)));
251         assertEquals(5, full.size());
252     }
253 
254     /**
255      * keySet.add will not add the element if it already exists in the set
256      */
testAdd2()257     public void testAdd2() {
258         Set full = populatedSet(3);
259         assertFalse(full.add(one));
260         assertEquals(3, full.size());
261     }
262 
263     /**
264      * keySet.add adds the element when it does not exist in the set
265      */
testAdd3()266     public void testAdd3() {
267         Set full = populatedSet(3);
268         assertTrue(full.add(three));
269         assertTrue(full.contains(three));
270         assertFalse(full.add(three));
271         assertTrue(full.contains(three));
272     }
273 
274     /**
275      * keySet.add throws UnsupportedOperationException if no default
276      * mapped value
277      */
testAdd4()278     public void testAdd4() {
279         Set full = map5().keySet();
280         try {
281             full.add(three);
282             shouldThrow();
283         } catch (UnsupportedOperationException success) {}
284     }
285 
286     /**
287      * keySet.add throws NullPointerException if the specified key is
288      * null
289      */
testAdd5()290     public void testAdd5() {
291         Set full = populatedSet(3);
292         try {
293             full.add(null);
294             shouldThrow();
295         } catch (NullPointerException success) {}
296     }
297 
298     /**
299      * KeySetView.getMappedValue returns the map's mapped value
300      */
testGetMappedValue()301     public void testGetMappedValue() {
302         ConcurrentHashMap map = map5();
303         assertNull(((ConcurrentHashMap.KeySetView) map.keySet()).getMappedValue());
304         try {
305             map.keySet(null);
306             shouldThrow();
307         } catch (NullPointerException success) {}
308         ConcurrentHashMap.KeySetView set = map.keySet(one);
309         assertFalse(set.add(one));
310         assertTrue(set.add(six));
311         assertTrue(set.add(seven));
312         assertTrue(set.getMappedValue() == one);
313         assertTrue(map.get(one) != one);
314         assertTrue(map.get(six) == one);
315         assertTrue(map.get(seven) == one);
316     }
317 
checkSpliteratorCharacteristics(Spliterator<?> sp, int requiredCharacteristics)318     void checkSpliteratorCharacteristics(Spliterator<?> sp,
319                                          int requiredCharacteristics) {
320         assertEquals(requiredCharacteristics,
321                      requiredCharacteristics & sp.characteristics());
322     }
323 
324     /**
325      * KeySetView.spliterator returns spliterator over the elements in this set
326      */
testKeySetSpliterator()327     public void testKeySetSpliterator() {
328         LongAdder adder = new LongAdder();
329         ConcurrentHashMap map = map5();
330         Set set = map.keySet();
331         Spliterator<Integer> sp = set.spliterator();
332         checkSpliteratorCharacteristics(sp, CONCURRENT | DISTINCT | NONNULL);
333         assertEquals(sp.estimateSize(), map.size());
334         Spliterator<Integer> sp2 = sp.trySplit();
335         sp.forEachRemaining((Integer x) -> adder.add(x.longValue()));
336         long v = adder.sumThenReset();
337         sp2.forEachRemaining((Integer x) -> adder.add(x.longValue()));
338         long v2 = adder.sum();
339         assertEquals(v + v2, 15);
340     }
341 
342     /**
343      * keyset.clear removes all elements from the set
344      */
testClear()345     public void testClear() {
346         Set full = populatedSet(3);
347         full.clear();
348         assertEquals(0, full.size());
349     }
350 
351     /**
352      * keyset.contains returns true for added elements
353      */
testContains()354     public void testContains() {
355         Set full = populatedSet(3);
356         assertTrue(full.contains(one));
357         assertFalse(full.contains(five));
358     }
359 
360     /**
361      * KeySets with equal elements are equal
362      */
testEquals()363     public void testEquals() {
364         Set a = populatedSet(3);
365         Set b = populatedSet(3);
366         assertTrue(a.equals(b));
367         assertTrue(b.equals(a));
368         assertEquals(a.hashCode(), b.hashCode());
369         a.add(m1);
370         assertFalse(a.equals(b));
371         assertFalse(b.equals(a));
372         b.add(m1);
373         assertTrue(a.equals(b));
374         assertTrue(b.equals(a));
375         assertEquals(a.hashCode(), b.hashCode());
376     }
377 
378     /**
379      * KeySet.containsAll returns true for collections with subset of elements
380      */
testContainsAll()381     public void testContainsAll() {
382         Collection full = populatedSet(3);
383         assertTrue(full.containsAll(Arrays.asList()));
384         assertTrue(full.containsAll(Arrays.asList(one)));
385         assertTrue(full.containsAll(Arrays.asList(one, two)));
386         assertFalse(full.containsAll(Arrays.asList(one, two, six)));
387         assertFalse(full.containsAll(Arrays.asList(six)));
388     }
389 
390     /**
391      * KeySet.isEmpty is true when empty, else false
392      */
testIsEmpty()393     public void testIsEmpty() {
394         assertTrue(populatedSet(0).isEmpty());
395         assertFalse(populatedSet(3).isEmpty());
396     }
397 
398     /**
399      * KeySet.iterator() returns an iterator containing the elements of the
400      * set
401      */
testIterator()402     public void testIterator() {
403         Collection empty = ConcurrentHashMap.newKeySet();
404         int size = 20;
405         assertFalse(empty.iterator().hasNext());
406         try {
407             empty.iterator().next();
408             shouldThrow();
409         } catch (NoSuchElementException success) {}
410 
411         Integer[] elements = new Integer[size];
412         for (int i = 0; i < size; i++)
413             elements[i] = i;
414         Collections.shuffle(Arrays.asList(elements));
415         Collection<Integer> full = populatedSet(elements);
416 
417         Iterator it = full.iterator();
418         for (int j = 0; j < size; j++) {
419             assertTrue(it.hasNext());
420             it.next();
421         }
422         assertIteratorExhausted(it);
423     }
424 
425     /**
426      * iterator of empty collections has no elements
427      */
testEmptyIterator()428     public void testEmptyIterator() {
429         assertIteratorExhausted(ConcurrentHashMap.newKeySet().iterator());
430         assertIteratorExhausted(new ConcurrentHashMap().entrySet().iterator());
431         assertIteratorExhausted(new ConcurrentHashMap().values().iterator());
432         assertIteratorExhausted(new ConcurrentHashMap().keySet().iterator());
433     }
434 
435     /**
436      * KeySet.iterator.remove removes current element
437      */
testIteratorRemove()438     public void testIteratorRemove() {
439         Set q = populatedSet(3);
440         Iterator it = q.iterator();
441         Object removed = it.next();
442         it.remove();
443 
444         it = q.iterator();
445         assertFalse(it.next().equals(removed));
446         assertFalse(it.next().equals(removed));
447         assertFalse(it.hasNext());
448     }
449 
450     /**
451      * KeySet.toString holds toString of elements
452      */
testToString()453     public void testToString() {
454         assertEquals("[]", ConcurrentHashMap.newKeySet().toString());
455         Set full = populatedSet(3);
456         String s = full.toString();
457         for (int i = 0; i < 3; ++i)
458             assertTrue(s.contains(String.valueOf(i)));
459     }
460 
461     /**
462      * KeySet.removeAll removes all elements from the given collection
463      */
testRemoveAll()464     public void testRemoveAll() {
465         Set full = populatedSet(3);
466         assertTrue(full.removeAll(Arrays.asList(one, two)));
467         assertEquals(1, full.size());
468         assertFalse(full.removeAll(Arrays.asList(one, two)));
469         assertEquals(1, full.size());
470     }
471 
472     /**
473      * KeySet.remove removes an element
474      */
testRemove()475     public void testRemove() {
476         Set full = populatedSet(3);
477         full.remove(one);
478         assertFalse(full.contains(one));
479         assertEquals(2, full.size());
480     }
481 
482     /**
483      * keySet.size returns the number of elements
484      */
testSize()485     public void testSize() {
486         Set empty = ConcurrentHashMap.newKeySet();
487         Set full = populatedSet(3);
488         assertEquals(3, full.size());
489         assertEquals(0, empty.size());
490     }
491 
492     /**
493      * KeySet.toArray() returns an Object array containing all elements from
494      * the set
495      */
testToArray()496     public void testToArray() {
497         Object[] a = ConcurrentHashMap.newKeySet().toArray();
498         assertTrue(Arrays.equals(new Object[0], a));
499         assertSame(Object[].class, a.getClass());
500         int size = 20;
501         Integer[] elements = new Integer[size];
502         for (int i = 0; i < size; i++)
503             elements[i] = i;
504         Collections.shuffle(Arrays.asList(elements));
505         Collection<Integer> full = populatedSet(elements);
506 
507         assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray())));
508         assertTrue(full.containsAll(Arrays.asList(full.toArray())));
509         assertSame(Object[].class, full.toArray().getClass());
510     }
511 
512     /**
513      * toArray(Integer array) returns an Integer array containing all
514      * elements from the set
515      */
testToArray2()516     public void testToArray2() {
517         Collection empty = ConcurrentHashMap.newKeySet();
518         Integer[] a;
519         int size = 20;
520 
521         a = new Integer[0];
522         assertSame(a, empty.toArray(a));
523 
524         a = new Integer[size / 2];
525         Arrays.fill(a, 42);
526         assertSame(a, empty.toArray(a));
527         assertNull(a[0]);
528         for (int i = 1; i < a.length; i++)
529             assertEquals(42, (int) a[i]);
530 
531         Integer[] elements = new Integer[size];
532         for (int i = 0; i < size; i++)
533             elements[i] = i;
534         Collections.shuffle(Arrays.asList(elements));
535         Collection<Integer> full = populatedSet(elements);
536 
537         Arrays.fill(a, 42);
538         assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray(a))));
539         for (int i = 0; i < a.length; i++)
540             assertEquals(42, (int) a[i]);
541         assertSame(Integer[].class, full.toArray(a).getClass());
542 
543         a = new Integer[size];
544         Arrays.fill(a, 42);
545         assertSame(a, full.toArray(a));
546         assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray(a))));
547     }
548 
549     /**
550      * A deserialized serialized set is equal
551      */
testSerialization()552     public void testSerialization() throws Exception {
553         int size = 20;
554         Set x = populatedSet(size);
555         Set y = serialClone(x);
556 
557         assertNotSame(x, y);
558         assertEquals(x.size(), y.size());
559         assertEquals(x, y);
560         assertEquals(y, x);
561     }
562 
563     static final int SIZE = 10000;
564     static ConcurrentHashMap<Long, Long> longMap;
565 
longMap()566     static ConcurrentHashMap<Long, Long> longMap() {
567         if (longMap == null) {
568             longMap = new ConcurrentHashMap<Long, Long>(SIZE);
569             for (int i = 0; i < SIZE; ++i)
570                 longMap.put(Long.valueOf(i), Long.valueOf(2 *i));
571         }
572         return longMap;
573     }
574 
575     // explicit function class to avoid type inference problems
576     static class AddKeys implements BiFunction<Map.Entry<Long,Long>, Map.Entry<Long,Long>, Map.Entry<Long,Long>> {
apply(Map.Entry<Long,Long> x, Map.Entry<Long,Long> y)577         public Map.Entry<Long,Long> apply(Map.Entry<Long,Long> x, Map.Entry<Long,Long> y) {
578             return new AbstractMap.SimpleEntry<Long,Long>
579              (Long.valueOf(x.getKey().longValue() + y.getKey().longValue()),
580               Long.valueOf(1L));
581         }
582     }
583 
584     /**
585      * forEachKeySequentially traverses all keys
586      */
testForEachKeySequentially()587     public void testForEachKeySequentially() {
588         LongAdder adder = new LongAdder();
589         ConcurrentHashMap<Long, Long> m = longMap();
590         m.forEachKey(Long.MAX_VALUE, (Long x) -> adder.add(x.longValue()));
591         assertEquals(adder.sum(), SIZE * (SIZE - 1) / 2);
592     }
593 
594     /**
595      * forEachValueSequentially traverses all values
596      */
testForEachValueSequentially()597     public void testForEachValueSequentially() {
598         LongAdder adder = new LongAdder();
599         ConcurrentHashMap<Long, Long> m = longMap();
600         m.forEachValue(Long.MAX_VALUE, (Long x) -> adder.add(x.longValue()));
601         assertEquals(adder.sum(), SIZE * (SIZE - 1));
602     }
603 
604     /**
605      * forEachSequentially traverses all mappings
606      */
testForEachSequentially()607     public void testForEachSequentially() {
608         LongAdder adder = new LongAdder();
609         ConcurrentHashMap<Long, Long> m = longMap();
610         m.forEach(Long.MAX_VALUE, (Long x, Long y) -> adder.add(x.longValue() + y.longValue()));
611         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
612     }
613 
614     /**
615      * forEachEntrySequentially traverses all entries
616      */
testForEachEntrySequentially()617     public void testForEachEntrySequentially() {
618         LongAdder adder = new LongAdder();
619         ConcurrentHashMap<Long, Long> m = longMap();
620         m.forEachEntry(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> adder.add(e.getKey().longValue() + e.getValue().longValue()));
621         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
622     }
623 
624     /**
625      * forEachKeyInParallel traverses all keys
626      */
testForEachKeyInParallel()627     public void testForEachKeyInParallel() {
628         LongAdder adder = new LongAdder();
629         ConcurrentHashMap<Long, Long> m = longMap();
630         m.forEachKey(1L, (Long x) -> adder.add(x.longValue()));
631         assertEquals(adder.sum(), SIZE * (SIZE - 1) / 2);
632     }
633 
634     /**
635      * forEachValueInParallel traverses all values
636      */
testForEachValueInParallel()637     public void testForEachValueInParallel() {
638         LongAdder adder = new LongAdder();
639         ConcurrentHashMap<Long, Long> m = longMap();
640         m.forEachValue(1L, (Long x) -> adder.add(x.longValue()));
641         assertEquals(adder.sum(), SIZE * (SIZE - 1));
642     }
643 
644     /**
645      * forEachInParallel traverses all mappings
646      */
testForEachInParallel()647     public void testForEachInParallel() {
648         LongAdder adder = new LongAdder();
649         ConcurrentHashMap<Long, Long> m = longMap();
650         m.forEach(1L, (Long x, Long y) -> adder.add(x.longValue() + y.longValue()));
651         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
652     }
653 
654     /**
655      * forEachEntryInParallel traverses all entries
656      */
testForEachEntryInParallel()657     public void testForEachEntryInParallel() {
658         LongAdder adder = new LongAdder();
659         ConcurrentHashMap<Long, Long> m = longMap();
660         m.forEachEntry(1L, (Map.Entry<Long,Long> e) -> adder.add(e.getKey().longValue() + e.getValue().longValue()));
661         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
662     }
663 
664     /**
665      * Mapped forEachKeySequentially traverses the given
666      * transformations of all keys
667      */
testMappedForEachKeySequentially()668     public void testMappedForEachKeySequentially() {
669         LongAdder adder = new LongAdder();
670         ConcurrentHashMap<Long, Long> m = longMap();
671         m.forEachKey(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
672                                  (Long x) -> adder.add(x.longValue()));
673         assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1) / 2);
674     }
675 
676     /**
677      * Mapped forEachValueSequentially traverses the given
678      * transformations of all values
679      */
testMappedForEachValueSequentially()680     public void testMappedForEachValueSequentially() {
681         LongAdder adder = new LongAdder();
682         ConcurrentHashMap<Long, Long> m = longMap();
683         m.forEachValue(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
684                                    (Long x) -> adder.add(x.longValue()));
685         assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1));
686     }
687 
688     /**
689      * Mapped forEachSequentially traverses the given
690      * transformations of all mappings
691      */
testMappedForEachSequentially()692     public void testMappedForEachSequentially() {
693         LongAdder adder = new LongAdder();
694         ConcurrentHashMap<Long, Long> m = longMap();
695         m.forEach(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
696                               (Long x) -> adder.add(x.longValue()));
697         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
698     }
699 
700     /**
701      * Mapped forEachEntrySequentially traverses the given
702      * transformations of all entries
703      */
testMappedForEachEntrySequentially()704     public void testMappedForEachEntrySequentially() {
705         LongAdder adder = new LongAdder();
706         ConcurrentHashMap<Long, Long> m = longMap();
707         m.forEachEntry(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> Long.valueOf(e.getKey().longValue() + e.getValue().longValue()),
708                                    (Long x) -> adder.add(x.longValue()));
709         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
710     }
711 
712     /**
713      * Mapped forEachKeyInParallel traverses the given
714      * transformations of all keys
715      */
testMappedForEachKeyInParallel()716     public void testMappedForEachKeyInParallel() {
717         LongAdder adder = new LongAdder();
718         ConcurrentHashMap<Long, Long> m = longMap();
719         m.forEachKey(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
720                                (Long x) -> adder.add(x.longValue()));
721         assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1) / 2);
722     }
723 
724     /**
725      * Mapped forEachValueInParallel traverses the given
726      * transformations of all values
727      */
testMappedForEachValueInParallel()728     public void testMappedForEachValueInParallel() {
729         LongAdder adder = new LongAdder();
730         ConcurrentHashMap<Long, Long> m = longMap();
731         m.forEachValue(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
732                                  (Long x) -> adder.add(x.longValue()));
733         assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1));
734     }
735 
736     /**
737      * Mapped forEachInParallel traverses the given
738      * transformations of all mappings
739      */
testMappedForEachInParallel()740     public void testMappedForEachInParallel() {
741         LongAdder adder = new LongAdder();
742         ConcurrentHashMap<Long, Long> m = longMap();
743         m.forEach(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
744                             (Long x) -> adder.add(x.longValue()));
745         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
746     }
747 
748     /**
749      * Mapped forEachEntryInParallel traverses the given
750      * transformations of all entries
751      */
testMappedForEachEntryInParallel()752     public void testMappedForEachEntryInParallel() {
753         LongAdder adder = new LongAdder();
754         ConcurrentHashMap<Long, Long> m = longMap();
755         m.forEachEntry(1L, (Map.Entry<Long,Long> e) -> Long.valueOf(e.getKey().longValue() + e.getValue().longValue()),
756                                  (Long x) -> adder.add(x.longValue()));
757         assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
758     }
759 
760     /**
761      * reduceKeysSequentially accumulates across all keys,
762      */
testReduceKeysSequentially()763     public void testReduceKeysSequentially() {
764         ConcurrentHashMap<Long, Long> m = longMap();
765         Long r;
766         r = m.reduceKeys(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
767         assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
768     }
769 
770     /**
771      * reduceValuesSequentially accumulates across all values
772      */
testReduceValuesSequentially()773     public void testReduceValuesSequentially() {
774         ConcurrentHashMap<Long, Long> m = longMap();
775         Long r;
776         r = m.reduceKeys(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
777         assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
778     }
779 
780     /**
781      * reduceEntriesSequentially accumulates across all entries
782      */
testReduceEntriesSequentially()783     public void testReduceEntriesSequentially() {
784         ConcurrentHashMap<Long, Long> m = longMap();
785         Map.Entry<Long,Long> r;
786         r = m.reduceEntries(Long.MAX_VALUE, new AddKeys());
787         assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
788     }
789 
790     /**
791      * reduceKeysInParallel accumulates across all keys
792      */
testReduceKeysInParallel()793     public void testReduceKeysInParallel() {
794         ConcurrentHashMap<Long, Long> m = longMap();
795         Long r;
796         r = m.reduceKeys(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
797         assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
798     }
799 
800     /**
801      * reduceValuesInParallel accumulates across all values
802      */
testReduceValuesInParallel()803     public void testReduceValuesInParallel() {
804         ConcurrentHashMap<Long, Long> m = longMap();
805         Long r;
806         r = m.reduceValues(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
807         assertEquals((long)r, (long)SIZE * (SIZE - 1));
808     }
809 
810     /**
811      * reduceEntriesInParallel accumulate across all entries
812      */
testReduceEntriesInParallel()813     public void testReduceEntriesInParallel() {
814         ConcurrentHashMap<Long, Long> m = longMap();
815         Map.Entry<Long,Long> r;
816         r = m.reduceEntries(1L, new AddKeys());
817         assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
818     }
819 
820     /**
821      * Mapped reduceKeysSequentially accumulates mapped keys
822      */
testMapReduceKeysSequentially()823     public void testMapReduceKeysSequentially() {
824         ConcurrentHashMap<Long, Long> m = longMap();
825         Long r = m.reduceKeys(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
826                                      (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
827         assertEquals((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
828     }
829 
830     /**
831      * Mapped reduceValuesSequentially accumulates mapped values
832      */
testMapReduceValuesSequentially()833     public void testMapReduceValuesSequentially() {
834         ConcurrentHashMap<Long, Long> m = longMap();
835         Long r = m.reduceValues(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
836                                        (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
837         assertEquals((long)r, (long)4 * SIZE * (SIZE - 1));
838     }
839 
840     /**
841      * reduceSequentially accumulates across all transformed mappings
842      */
testMappedReduceSequentially()843     public void testMappedReduceSequentially() {
844         ConcurrentHashMap<Long, Long> m = longMap();
845         Long r = m.reduce(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
846                                  (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
847 
848         assertEquals((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
849     }
850 
851     /**
852      * Mapped reduceKeysInParallel, accumulates mapped keys
853      */
testMapReduceKeysInParallel()854     public void testMapReduceKeysInParallel() {
855         ConcurrentHashMap<Long, Long> m = longMap();
856         Long r = m.reduceKeys(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
857                                    (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
858         assertEquals((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
859     }
860 
861     /**
862      * Mapped reduceValuesInParallel accumulates mapped values
863      */
testMapReduceValuesInParallel()864     public void testMapReduceValuesInParallel() {
865         ConcurrentHashMap<Long, Long> m = longMap();
866         Long r = m.reduceValues(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
867                                      (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
868         assertEquals((long)r, (long)4 * SIZE * (SIZE - 1));
869     }
870 
871     /**
872      * reduceInParallel accumulate across all transformed mappings
873      */
testMappedReduceInParallel()874     public void testMappedReduceInParallel() {
875         ConcurrentHashMap<Long, Long> m = longMap();
876         Long r;
877         r = m.reduce(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
878                                (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
879         assertEquals((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
880     }
881 
882     /**
883      * reduceKeysToLongSequentially accumulates mapped keys
884      */
testReduceKeysToLongSequentially()885     public void testReduceKeysToLongSequentially() {
886         ConcurrentHashMap<Long, Long> m = longMap();
887         long lr = m.reduceKeysToLong(Long.MAX_VALUE, (Long x) -> x.longValue(), 0L, Long::sum);
888         assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
889     }
890 
891     /**
892      * reduceKeysToIntSequentially accumulates mapped keys
893      */
testReduceKeysToIntSequentially()894     public void testReduceKeysToIntSequentially() {
895         ConcurrentHashMap<Long, Long> m = longMap();
896         int ir = m.reduceKeysToInt(Long.MAX_VALUE, (Long x) -> x.intValue(), 0, Integer::sum);
897         assertEquals(ir, SIZE * (SIZE - 1) / 2);
898     }
899 
900     /**
901      * reduceKeysToDoubleSequentially accumulates mapped keys
902      */
testReduceKeysToDoubleSequentially()903     public void testReduceKeysToDoubleSequentially() {
904         ConcurrentHashMap<Long, Long> m = longMap();
905         double dr = m.reduceKeysToDouble(Long.MAX_VALUE, (Long x) -> x.doubleValue(), 0.0, Double::sum);
906         assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
907     }
908 
909     /**
910      * reduceValuesToLongSequentially accumulates mapped values
911      */
testReduceValuesToLongSequentially()912     public void testReduceValuesToLongSequentially() {
913         ConcurrentHashMap<Long, Long> m = longMap();
914         long lr = m.reduceValuesToLong(Long.MAX_VALUE, (Long x) -> x.longValue(), 0L, Long::sum);
915         assertEquals(lr, (long)SIZE * (SIZE - 1));
916     }
917 
918     /**
919      * reduceValuesToIntSequentially accumulates mapped values
920      */
testReduceValuesToIntSequentially()921     public void testReduceValuesToIntSequentially() {
922         ConcurrentHashMap<Long, Long> m = longMap();
923         int ir = m.reduceValuesToInt(Long.MAX_VALUE, (Long x) -> x.intValue(), 0, Integer::sum);
924         assertEquals(ir, SIZE * (SIZE - 1));
925     }
926 
927     /**
928      * reduceValuesToDoubleSequentially accumulates mapped values
929      */
testReduceValuesToDoubleSequentially()930     public void testReduceValuesToDoubleSequentially() {
931         ConcurrentHashMap<Long, Long> m = longMap();
932         double dr = m.reduceValuesToDouble(Long.MAX_VALUE, (Long x) -> x.doubleValue(), 0.0, Double::sum);
933         assertEquals(dr, (double)SIZE * (SIZE - 1));
934     }
935 
936     /**
937      * reduceKeysToLongInParallel accumulates mapped keys
938      */
testReduceKeysToLongInParallel()939     public void testReduceKeysToLongInParallel() {
940         ConcurrentHashMap<Long, Long> m = longMap();
941         long lr = m.reduceKeysToLong(1L, (Long x) -> x.longValue(), 0L, Long::sum);
942         assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
943     }
944 
945     /**
946      * reduceKeysToIntInParallel accumulates mapped keys
947      */
testReduceKeysToIntInParallel()948     public void testReduceKeysToIntInParallel() {
949         ConcurrentHashMap<Long, Long> m = longMap();
950         int ir = m.reduceKeysToInt(1L, (Long x) -> x.intValue(), 0, Integer::sum);
951         assertEquals(ir, SIZE * (SIZE - 1) / 2);
952     }
953 
954     /**
955      * reduceKeysToDoubleInParallel accumulates mapped values
956      */
testReduceKeysToDoubleInParallel()957     public void testReduceKeysToDoubleInParallel() {
958         ConcurrentHashMap<Long, Long> m = longMap();
959         double dr = m.reduceKeysToDouble(1L, (Long x) -> x.doubleValue(), 0.0, Double::sum);
960         assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
961     }
962 
963     /**
964      * reduceValuesToLongInParallel accumulates mapped values
965      */
testReduceValuesToLongInParallel()966     public void testReduceValuesToLongInParallel() {
967         ConcurrentHashMap<Long, Long> m = longMap();
968         long lr = m.reduceValuesToLong(1L, (Long x) -> x.longValue(), 0L, Long::sum);
969         assertEquals(lr, (long)SIZE * (SIZE - 1));
970     }
971 
972     /**
973      * reduceValuesToIntInParallel accumulates mapped values
974      */
testReduceValuesToIntInParallel()975     public void testReduceValuesToIntInParallel() {
976         ConcurrentHashMap<Long, Long> m = longMap();
977         int ir = m.reduceValuesToInt(1L, (Long x) -> x.intValue(), 0, Integer::sum);
978         assertEquals(ir, SIZE * (SIZE - 1));
979     }
980 
981     /**
982      * reduceValuesToDoubleInParallel accumulates mapped values
983      */
testReduceValuesToDoubleInParallel()984     public void testReduceValuesToDoubleInParallel() {
985         ConcurrentHashMap<Long, Long> m = longMap();
986         double dr = m.reduceValuesToDouble(1L, (Long x) -> x.doubleValue(), 0.0, Double::sum);
987         assertEquals(dr, (double)SIZE * (SIZE - 1));
988     }
989 
990     /**
991      * searchKeysSequentially returns a non-null result of search
992      * function, or null if none
993      */
testSearchKeysSequentially()994     public void testSearchKeysSequentially() {
995         ConcurrentHashMap<Long, Long> m = longMap();
996         Long r;
997         r = m.searchKeys(Long.MAX_VALUE, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
998         assertEquals((long)r, (long)(SIZE/2));
999         r = m.searchKeys(Long.MAX_VALUE, (Long x) -> x.longValue() < 0L ? x : null);
1000         assertNull(r);
1001     }
1002 
1003     /**
1004      * searchValuesSequentially returns a non-null result of search
1005      * function, or null if none
1006      */
testSearchValuesSequentially()1007     public void testSearchValuesSequentially() {
1008         ConcurrentHashMap<Long, Long> m = longMap();
1009         Long r;
1010         r = m.searchValues(Long.MAX_VALUE,
1011             (Long x) -> (x.longValue() == (long)(SIZE/2)) ? x : null);
1012         assertEquals((long)r, (long)(SIZE/2));
1013         r = m.searchValues(Long.MAX_VALUE,
1014             (Long x) -> (x.longValue() < 0L) ? x : null);
1015         assertNull(r);
1016     }
1017 
1018     /**
1019      * searchSequentially returns a non-null result of search
1020      * function, or null if none
1021      */
testSearchSequentially()1022     public void testSearchSequentially() {
1023         ConcurrentHashMap<Long, Long> m = longMap();
1024         Long r;
1025         r = m.search(Long.MAX_VALUE, (Long x, Long y) -> x.longValue() == (long)(SIZE/2) ? x : null);
1026         assertEquals((long)r, (long)(SIZE/2));
1027         r = m.search(Long.MAX_VALUE, (Long x, Long y) -> x.longValue() < 0L ? x : null);
1028         assertNull(r);
1029     }
1030 
1031     /**
1032      * searchEntriesSequentially returns a non-null result of search
1033      * function, or null if none
1034      */
testSearchEntriesSequentially()1035     public void testSearchEntriesSequentially() {
1036         ConcurrentHashMap<Long, Long> m = longMap();
1037         Long r;
1038         r = m.searchEntries(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> e.getKey().longValue() == (long)(SIZE/2) ? e.getKey() : null);
1039         assertEquals((long)r, (long)(SIZE/2));
1040         r = m.searchEntries(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> e.getKey().longValue() < 0L ? e.getKey() : null);
1041         assertNull(r);
1042     }
1043 
1044     /**
1045      * searchKeysInParallel returns a non-null result of search
1046      * function, or null if none
1047      */
testSearchKeysInParallel()1048     public void testSearchKeysInParallel() {
1049         ConcurrentHashMap<Long, Long> m = longMap();
1050         Long r;
1051         r = m.searchKeys(1L, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
1052         assertEquals((long)r, (long)(SIZE/2));
1053         r = m.searchKeys(1L, (Long x) -> x.longValue() < 0L ? x : null);
1054         assertNull(r);
1055     }
1056 
1057     /**
1058      * searchValuesInParallel returns a non-null result of search
1059      * function, or null if none
1060      */
testSearchValuesInParallel()1061     public void testSearchValuesInParallel() {
1062         ConcurrentHashMap<Long, Long> m = longMap();
1063         Long r;
1064         r = m.searchValues(1L, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
1065         assertEquals((long)r, (long)(SIZE/2));
1066         r = m.searchValues(1L, (Long x) -> x.longValue() < 0L ? x : null);
1067         assertNull(r);
1068     }
1069 
1070     /**
1071      * searchInParallel returns a non-null result of search function,
1072      * or null if none
1073      */
testSearchInParallel()1074     public void testSearchInParallel() {
1075         ConcurrentHashMap<Long, Long> m = longMap();
1076         Long r;
1077         r = m.search(1L, (Long x, Long y) -> x.longValue() == (long)(SIZE/2) ? x : null);
1078         assertEquals((long)r, (long)(SIZE/2));
1079         r = m.search(1L, (Long x, Long y) -> x.longValue() < 0L ? x : null);
1080         assertNull(r);
1081     }
1082 
1083     /**
1084      * searchEntriesInParallel returns a non-null result of search
1085      * function, or null if none
1086      */
testSearchEntriesInParallel()1087     public void testSearchEntriesInParallel() {
1088         ConcurrentHashMap<Long, Long> m = longMap();
1089         Long r;
1090         r = m.searchEntries(1L, (Map.Entry<Long,Long> e) -> e.getKey().longValue() == (long)(SIZE/2) ? e.getKey() : null);
1091         assertEquals((long)r, (long)(SIZE/2));
1092         r = m.searchEntries(1L, (Map.Entry<Long,Long> e) -> e.getKey().longValue() < 0L ? e.getKey() : null);
1093         assertNull(r);
1094     }
1095 
1096 }
1097