1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 8205399 27 * @summary Check for AssertionError from HashMap TreeBin after Iterator.remove 28 * @run testng/othervm -esa TreeBinAssert 29 */ 30 31 package test.java.util.HashMap; 32 33 import org.testng.annotations.DataProvider; 34 import org.testng.annotations.Test; 35 import org.testng.annotations.BeforeTest; 36 import java.util.Map; 37 import java.util.Set; 38 import java.util.Iterator; 39 import java.util.HashMap; 40 import java.util.LinkedHashSet; 41 import java.util.function.BiConsumer; 42 import java.util.function.Function; 43 44 public class TreeBinAssert { 45 private static final int ITR_RM = -1; // Remove an item via Iterator 46 private static final int BIN352442_SIZE = 524288; 47 private static final int BIN552165_SIZE = 1048576; 48 49 @DataProvider(name = "SizeAndHashes") sizeAndHashes()50 public Object[][] sizeAndHashes() { 51 return new Object[][] { 52 { // Bin 352442 53 BIN352442_SIZE, 54 new int[] { 55 2020958394, 56 631595194, 57 1984782522, 58 419782842, 59 285565114, 60 1432182970, 61 841310394, 62 320692410, 63 303390906, 64 ITR_RM, 65 ITR_RM, 66 ITR_RM, 67 ITR_RM, 68 ITR_RM, 69 ITR_RM, 70 ITR_RM, 71 ITR_RM, 72 519397562, 73 ITR_RM, 74 626352314, 75 101540026 76 } 77 },{ // Bin 552165 78 BIN552165_SIZE, 79 new int[] { 80 790129893, 81 1214803173, 82 1212706021, 83 608726245, 84 2073586917, 85 1433955557, 86 692612325, 87 370699493, 88 2061004005, 89 48786661, 90 ITR_RM, 91 ITR_RM, 92 1418226917, 93 ITR_RM, 94 ITR_RM, 95 ITR_RM, 96 ITR_RM, 97 ITR_RM, 98 ITR_RM, 99 ITR_RM, 100 1487432933, 101 ITR_RM, 102 ITR_RM, 103 1880648933, 104 338193637 105 } 106 } 107 }; 108 } 109 110 @BeforeTest checkAssertionStatus()111 public void checkAssertionStatus() { 112 if (!HashMap.class.desiredAssertionStatus()) { 113 System.out.println("*** Superficial test run. Test should be run with -esa ***\n"); 114 return; 115 } 116 } 117 118 @Test(dataProvider = "SizeAndHashes") testMap(int size, int[] hashes)119 public void testMap(int size, int[] hashes) { 120 Map<Key,Integer> map = new HashMap<>(size); 121 122 doTest(map, hashes, 123 (c,k) -> { ((Map<Key,Integer>)c).put(k,0); }, 124 (c) -> { return ((Map<Key,Integer>)c).keySet().iterator(); } 125 ); 126 } 127 128 @Test(dataProvider = "SizeAndHashes") testSet(int size, int[] hashes)129 public void testSet(int size, int[] hashes) { 130 Set<Key> set = new LinkedHashSet<>(size); 131 132 doTest(set, hashes, 133 (c,k) -> { ((Set<Key>)c).add(k); }, 134 (c) -> { return ((Set<Key>)c).iterator(); } 135 ); 136 } 137 doTest(Object collection, int[] hashes, BiConsumer<Object,Key> addKey, Function<Object,Iterator<Key>> mkItr)138 private void doTest(Object collection, int[] hashes, 139 BiConsumer<Object,Key> addKey, 140 Function<Object,Iterator<Key>> mkItr) { 141 Iterator<Key> itr = null; // saved iterator, used for removals 142 for (int h : hashes) { 143 if (h == ITR_RM) { 144 if (itr == null) { 145 itr = mkItr.apply(collection); 146 } 147 itr.next(); 148 itr.remove(); 149 } else { 150 itr = null; 151 addKey.accept(collection, new Key(h)); 152 } 153 } 154 } 155 156 /** 157 * Class that will have specified hash code in a HashMap. 158 */ 159 static class Key implements Comparable<Key> { 160 final int hash; 161 Key(int desiredHash)162 public Key(int desiredHash) { 163 // Account for processing done by HashMap 164 this.hash = desiredHash ^ (desiredHash >>> 16); 165 } 166 hashCode()167 @Override public int hashCode() { return this.hash; } 168 equals(Object o)169 @Override public boolean equals(Object o) { 170 return o.hashCode() == this.hashCode(); 171 } 172 compareTo(Key k)173 @Override public int compareTo(Key k) { 174 return Integer.compare(this.hash, k.hash); 175 } 176 } 177 } 178