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.1 by dl, Thu Mar 21 19:06:54 2013 UTC vs.
Revision 1.38 by dl, Tue Jan 26 13:33:05 2021 UTC

# Line 2 | Line 2
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 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
5   */
6  
7 < import junit.framework.*;
8 < import java.util.*;
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<Item,String>(5);
41          assertTrue(map.isEmpty());
42          map.put(one, "A");
43          map.put(two, "B");
# Line 30 | 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 73 | 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 90 | 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 115 | 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 +
557 +    static ConcurrentHashMap<Long, Long> longMap() {
558 +        if (longMap == null) {
559 +            longMap = new ConcurrentHashMap<Long, Long>(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 +     * 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 traverses the given
657 +     * transformations of all keys
658 +     */
659 +    public void testMappedForEachKeySequentially() {
660 +        LongAdder adder = new LongAdder();
661 +        ConcurrentHashMap<Long, Long> m = longMap();
662 +        m.forEachKey(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
663 +                                 (Long x) -> adder.add(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 +        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 +        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 +        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 +        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 +        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 +        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 +        mustEqual(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
749 +    }
750 +
751 +    /**
752 +     * reduceKeysSequentially accumulates across all keys,
753 +     */
754 +    public void testReduceKeysSequentially() {
755 +        ConcurrentHashMap<Long, Long> m = longMap();
756 +        Long r;
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 testReduceEntriesInParallel() {
805 +        ConcurrentHashMap<Long, Long> m = longMap();
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 +        mustEqual((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
819 +    }
820 +
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 +        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 +        mustEqual((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
840 +    }
841 +
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 +        mustEqual((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
850 +    }
851 +
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 +        mustEqual((long)r, (long)4 * SIZE * (SIZE - 1));
860 +    }
861 +
862 +    /**
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 +    /**
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 +    }
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 +    /**
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 +    /**
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 +    }
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 +    }
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 +    }
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 +     * searchEntriesInParallel returns a non-null result of search
1076 +     * function, or null if none
1077 +     */
1078 +    public void testSearchEntriesInParallel() {
1079 +        ConcurrentHashMap<Long, Long> m = longMap();
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