1 import org.testng.annotations.Test; 2 3 import java.lang.invoke.MethodHandle; 4 import java.lang.invoke.MethodHandles; 5 import java.lang.invoke.MethodType; 6 import java.lang.invoke.VarHandle; 7 import java.util.HashMap; 8 import java.util.stream.IntStream; 9 10 import static java.util.stream.Collectors.toMap; 11 import static org.testng.Assert.assertEquals; 12 13 /** 14 * @test 15 * @bug 8210280 16 * @run testng ResizeTest 17 */ 18 19 public class ResizeTest { 20 final MethodHandle TABLE_SIZE_FOR; 21 final MethodHandle RESIZE; 22 final VarHandle THRESHOLD; 23 final VarHandle TABLE; 24 25 public ResizeTest() throws IllegalAccessException, NoSuchMethodException, NoSuchFieldException, 26 ClassNotFoundException { 27 Class<?> mClass = HashMap.class; 28 String nodeClassName = mClass.getName() + "$Node"; 29 Class<?> nodeArrayClass = Class.forName("[L" + nodeClassName + ";"); 30 MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(mClass, MethodHandles.lookup()); 31 TABLE = lookup.findVarHandle(mClass, "table", nodeArrayClass); 32 this.TABLE_SIZE_FOR = lookup.findStatic( 33 mClass, "tableSizeFor", 34 MethodType.methodType(int.class, int.class)); 35 this.RESIZE = lookup.findVirtual(mClass, "resize", MethodType.methodType(nodeArrayClass, int.class)); 36 this.THRESHOLD = lookup.findVarHandle(mClass, "threshold", int.class); 37 } 38 39 int tableSizeFor(int n) { 40 try { 41 return (int) TABLE_SIZE_FOR.invoke(n); 42 } catch (Throwable t) { throw new AssertionError(t); } 43 } 44 45 @Test 46 public void testTableSizeFor() { 47 assertEquals(tableSizeFor(0), 1); 48 assertEquals(tableSizeFor(1), 1); 49 assertEquals(tableSizeFor(2), 2); 50 assertEquals(tableSizeFor(3), 4); 51 assertEquals(tableSizeFor(15), 16); 52 assertEquals(tableSizeFor(16), 16); 53 assertEquals(tableSizeFor(17), 32); 54 int maxSize = 1 << 30; 55 assertEquals(tableSizeFor(maxSize - 1), maxSize); 56 assertEquals(tableSizeFor(maxSize), maxSize); 57 assertEquals(tableSizeFor(maxSize + 1), maxSize); 58 assertEquals(tableSizeFor(Integer.MAX_VALUE), maxSize); 59 } 60 61 @Test 62 public void putAllCapacityTest() { 63 var map = new HashMap<Integer, Integer>(); 64 map.putAll(IntStream.range(0, 10).boxed().collect(toMap(i -> i, i -> i))); 65 66 int capacity = ((Object[]) TABLE.get(map)).length; 67 assertEquals(capacity, 16); 68 } 69 70 @Test 71 public void callResizeWithSizeTest() throws Throwable { 72 var map = new HashMap<Integer, Integer>(); 73 74 RESIZE.invoke(map, 0); 75 int capacity = ((Object[]) TABLE.get(map)).length; 76 assertEquals(capacity, 1); 77 78 RESIZE.invoke(map, 15); 79 capacity = ((Object[]) TABLE.get(map)).length; 80 assertEquals(capacity, 16); 81 82 RESIZE.invoke(map, 256); 83 capacity = ((Object[]) TABLE.get(map)).length; 84 assertEquals(capacity, 256); 85 86 RESIZE.invoke(map, 257); 87 capacity = ((Object[]) TABLE.get(map)).length; 88 assertEquals(capacity, 512); 89 } 90 }