ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentHashMap8Test.java
(Generate patch)

Comparing jsr166/src/test/tck/ConcurrentHashMap8Test.java (file contents):
Revision 1.2 by dl, Fri Mar 22 00:24:35 2013 UTC vs.
Revision 1.39 by jsr166, Wed Jan 27 01:57:24 2021 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines