8215194: Initial size of UnicodeBlock map is incorrect
authornaoto
Tue, 11 Dec 2018 13:13:18 -0800
changeset 52954 799e964e32b6
parent 52953 b75a44aad06c
child 52955 f0f3dc30e3bb
8215194: Initial size of UnicodeBlock map is incorrect Reviewed-by: rriggs, rgoel, igerasim
src/java.base/share/classes/java/lang/Character.java
test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java
--- a/src/java.base/share/classes/java/lang/Character.java	Tue Dec 11 13:10:14 2018 -0800
+++ b/src/java.base/share/classes/java/lang/Character.java	Tue Dec 11 13:13:18 2018 -0800
@@ -681,11 +681,12 @@
      */
     public static final class UnicodeBlock extends Subset {
         /**
-         * 649  - the expected number of entities
+         * 667  - the expected number of entities
          * 0.75 - the default load factor of HashMap
          */
+        private static final int NUM_ENTITIES = 667;
         private static Map<String, UnicodeBlock> map =
-                new HashMap<>((int)(649 / 0.75f + 1.0f));
+                new HashMap<>((int)(NUM_ENTITIES / 0.75f + 1.0f));
 
         /**
          * Creates a UnicodeBlock with the given identifier name.
--- a/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java	Tue Dec 11 13:10:14 2018 -0800
+++ b/test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java	Tue Dec 11 13:13:18 2018 -0800
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8080535 8191410
+ * @bug 8080535 8191410 8215194
  * @summary Expected size of Character.UnicodeBlock.map is not optimal
  * @library /test/lib
  * @modules java.base/java.lang:open
@@ -32,6 +32,7 @@
  * @run main OptimalMapSize
  */
 
+import java.lang.reflect.Field;
 import jdk.test.lib.util.OptimalCapacity;
 
 // What will be the number of the Unicode blocks in the future.
@@ -44,14 +45,24 @@
 // After implementing support of Unicode 9 and 10 in Java, there will
 // be 638 entries in Character.UnicodeBlock.map.
 //
+// As of Unicode 11, 667 entries are expected.
+//
 // Initialization of the map and this test will have to be adjusted
 // accordingly then.
+//
+// Note that HashMap's implementation aligns the initial capacity to
+// a power of two size, so it will end up 1024 (and thus succeed) in
+// cases, such as 638 and 667.
 
 public class OptimalMapSize {
     public static void main(String[] args) throws Throwable {
         // The initial size of Character.UnicodeBlock.map.
         // See src/java.base/share/classes/java/lang/Character.java
-        int initialCapacity = (int)(638 / 0.75f + 1.0f);
+        Field f = Character.UnicodeBlock.class.getDeclaredField("NUM_ENTITIES");
+        f.setAccessible(true);
+        int num_entities = f.getInt(null);
+        assert num_entities == 667;
+        int initialCapacity = (int)(num_entities / 0.75f + 1.0f);
 
         OptimalCapacity.ofHashMap(Character.UnicodeBlock.class,
                 "map", initialCapacity);