JDK-8210280 - Unnecessary reallocation when invoking HashMap.putAll()

Martin Buchholz martinrb at google.com
Wed Dec 19 14:47:46 UTC 2018


Let's add whitebox tests for initial capacity and LinkedHashMap, as with
ConcurrentHashMap's whitebox tests.

--- src/test/jtreg/util/HashMap/WhiteBoxResizeTest.java 18 Dec 2018
20:21:24 -0000 1.1
+++ src/test/jtreg/util/HashMap/WhiteBoxResizeTest.java 19 Dec 2018
14:35:50 -0000
@@ -27,7 +27,11 @@
 import java.lang.invoke.MethodType;
 import java.lang.invoke.VarHandle;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Supplier;
 import java.util.stream.IntStream;

 import static java.util.stream.Collectors.toMap;
@@ -42,6 +46,7 @@
  * @run testng WhiteBoxResizeTest
  */
 public class WhiteBoxResizeTest {
+    final ThreadLocalRandom rnd = ThreadLocalRandom.current();
     final MethodHandle TABLE_SIZE_FOR;
     final VarHandle THRESHOLD;
     final VarHandle TABLE;
@@ -91,14 +96,36 @@
     }

     @Test
-    public void capacityTest() {
-        HashMap<Integer, Integer> map = new HashMap<>();
+    public void capacityTestDefaultConstructor() {
+        capacityTestDefaultConstructor(new HashMap<>());
+        capacityTestDefaultConstructor(new LinkedHashMap<>());
+    }
+
+    void capacityTestDefaultConstructor(HashMap<Integer, Integer> map) {
         assertNull(table(map));

         map.put(1, 1);
-        assertEquals(capacity(map), 16);
+        assertEquals(capacity(map), 16); // default initial capacity

         map.putAll(IntStream.range(0, 64).boxed().collect(toMap(i -> i, i
-> i)));
         assertEquals(capacity(map), 128);
     }
+
+    @Test
+    public void capacityTestInitialCapacity() {
+        int initialCapacity = rnd.nextInt(1, 256);
+        List<Supplier<HashMap<Integer, Integer>>> suppliers = List.of(
+            () -> new HashMap<>(initialCapacity),
+            () -> new HashMap<>(initialCapacity, 0.75f),
+            () -> new LinkedHashMap<>(initialCapacity),
+            () -> new LinkedHashMap<>(initialCapacity, 0.75f));
+
+        for (Supplier<HashMap<Integer, Integer>> supplier : suppliers) {
+            HashMap<Integer, Integer> map = supplier.get();
+            assertNull(table(map));
+
+            map.put(1, 1);
+            assertEquals(capacity(map), tableSizeFor(initialCapacity));
+        }
+    }
 }


More information about the core-libs-dev mailing list