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
7package jsr166;
8
9import static java.util.Spliterator.CONCURRENT;
10import static java.util.Spliterator.DISTINCT;
11import static java.util.Spliterator.NONNULL;
12
13import java.util.AbstractMap;
14import java.util.Arrays;
15import java.util.Collection;
16import java.util.Collections;
17import java.util.Iterator;
18import java.util.Map;
19import java.util.NoSuchElementException;
20import java.util.Set;
21import java.util.Spliterator;
22import java.util.concurrent.ConcurrentHashMap;
23import java.util.concurrent.atomic.LongAdder;
24import java.util.function.BiFunction;
25
26import junit.framework.Test;
27import junit.framework.TestSuite;
28
29public 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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
161    public void testMerge3() {
162        ConcurrentHashMap map = map5();
163        map.merge(one, "Y", (x, y) -> null);
164        assertFalse(map.containsKey(one));
165    }
166
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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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>> {
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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