1 /* 2 * Copyright (c) 2012, 2016, 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 * @test 25 * @bug 7126277 26 * @run testng/othervm -Dtest.map.collisions.shortrun=true Collisions 27 * @summary Ensure Maps behave well with lots of hashCode() collisions. 28 */ 29 package test.java.util.Map; 30 31 import java.util.BitSet; 32 import java.util.IdentityHashMap; 33 import java.util.Iterator; 34 import java.util.Map; 35 import java.util.function.Supplier; 36 37 import org.testng.annotations.Test; 38 import static org.testng.Assert.assertTrue; 39 import static org.testng.Assert.assertFalse; 40 import static org.testng.Assert.assertEquals; 41 import static org.testng.Assert.assertNotNull; 42 43 public class Collisions extends MapWithCollisionsProviders { 44 45 @Test(dataProvider = "mapsWithObjects") testIntegerIteration(String desc, Supplier<Map<IntKey, IntKey>> ms, IntKey val)46 public void testIntegerIteration(String desc, Supplier<Map<IntKey, IntKey>> ms, IntKey val) { 47 Map<IntKey, IntKey> map = ms.get(); 48 int mapSize = map.size(); 49 50 BitSet all = new BitSet(mapSize); 51 for (Map.Entry<IntKey, IntKey> each : map.entrySet()) { 52 assertFalse(all.get(each.getKey().getValue()), "Iteration: key already seen"); 53 all.set(each.getKey().getValue()); 54 } 55 56 all.flip(0, mapSize); 57 assertTrue(all.isEmpty(), "Iteration: some keys not visited"); 58 59 for (IntKey each : map.keySet()) { 60 assertFalse(all.get(each.getValue()), "Iteration: key already seen"); 61 all.set(each.getValue()); 62 } 63 64 all.flip(0, mapSize); 65 assertTrue(all.isEmpty(), "Iteration: some keys not visited"); 66 67 int count = 0; 68 for (IntKey each : map.values()) { 69 count++; 70 } 71 72 assertEquals(map.size(), count, 73 String.format("Iteration: value count matches size m%d != c%d", map.size(), count)); 74 } 75 76 @Test(dataProvider = "mapsWithStrings") testStringIteration(String desc, Supplier<Map<String, String>> ms, String val)77 public void testStringIteration(String desc, Supplier<Map<String, String>> ms, String val) { 78 Map<String, String> map = ms.get(); 79 int mapSize = map.size(); 80 81 BitSet all = new BitSet(mapSize); 82 for (Map.Entry<String, String> each : map.entrySet()) { 83 String key = each.getKey(); 84 boolean longKey = key.length() > 5; 85 int index = key.hashCode() + (longKey ? mapSize / 2 : 0); 86 assertFalse(all.get(index), "key already seen"); 87 all.set(index); 88 } 89 90 all.flip(0, mapSize); 91 assertTrue(all.isEmpty(), "some keys not visited"); 92 93 for (String each : map.keySet()) { 94 boolean longKey = each.length() > 5; 95 int index = each.hashCode() + (longKey ? mapSize / 2 : 0); 96 assertFalse(all.get(index), "key already seen"); 97 all.set(index); 98 } 99 100 all.flip(0, mapSize); 101 assertTrue(all.isEmpty(), "some keys not visited"); 102 103 int count = 0; 104 for (String each : map.values()) { 105 count++; 106 } 107 108 assertEquals(map.size(), mapSize, 109 String.format("value count matches size m%d != k%d", map.size(), mapSize)); 110 } 111 112 @Test(dataProvider = "mapsWithObjectsAndStrings") testRemove(String desc, Supplier<Map<Object, Object>> ms, Object val)113 public void testRemove(String desc, Supplier<Map<Object, Object>> ms, Object val) { 114 Map<Object, Object> map = ms.get(); 115 Object[] keys = map.keySet().toArray(); 116 117 for (int i = 0; i < keys.length; i++) { 118 Object each = keys[i]; 119 assertNotNull(map.remove(each), 120 String.format("remove: %s[%d]%s", desc, i, each)); 121 } 122 123 assertTrue(map.size() == 0 && map.isEmpty(), 124 String.format("remove: map empty. size=%d", map.size())); 125 } 126 127 @Test(dataProvider = "mapsWithObjectsAndStrings") testKeysIteratorRemove(String desc, Supplier<Map<Object, Object>> ms, Object val)128 public void testKeysIteratorRemove(String desc, Supplier<Map<Object, Object>> ms, Object val) { 129 Map<Object, Object> map = ms.get(); 130 131 Iterator<Object> each = map.keySet().iterator(); 132 while (each.hasNext()) { 133 Object t = each.next(); 134 each.remove(); 135 assertFalse(map.containsKey(t), String.format("not removed: %s", each)); 136 } 137 138 assertTrue(map.size() == 0 && map.isEmpty(), 139 String.format("remove: map empty. size=%d", map.size())); 140 } 141 142 @Test(dataProvider = "mapsWithObjectsAndStrings") testValuesIteratorRemove(String desc, Supplier<Map<Object, Object>> ms, Object val)143 public void testValuesIteratorRemove(String desc, Supplier<Map<Object, Object>> ms, Object val) { 144 Map<Object, Object> map = ms.get(); 145 146 Iterator<Object> each = map.values().iterator(); 147 while (each.hasNext()) { 148 Object t = each.next(); 149 each.remove(); 150 assertFalse(map.containsValue(t), String.format("not removed: %s", each)); 151 } 152 153 assertTrue(map.size() == 0 && map.isEmpty(), 154 String.format("remove: map empty. size=%d", map.size())); 155 } 156 157 @Test(dataProvider = "mapsWithObjectsAndStrings") testEntriesIteratorRemove(String desc, Supplier<Map<Object, Object>> ms, Object val)158 public void testEntriesIteratorRemove(String desc, Supplier<Map<Object, Object>> ms, Object val) { 159 Map<Object, Object> map = ms.get(); 160 161 Iterator<Map.Entry<Object, Object>> each = map.entrySet().iterator(); 162 while (each.hasNext()) { 163 Map.Entry<Object, Object> t = each.next(); 164 Object key = t.getKey(); 165 Object value = t.getValue(); 166 each.remove(); 167 assertTrue((map instanceof IdentityHashMap) || !map.entrySet().contains(t), 168 String.format("not removed: %s", each)); 169 assertFalse(map.containsKey(key), 170 String.format("not removed: %s", each)); 171 assertFalse(map.containsValue(value), 172 String.format("not removed: %s", each)); 173 } 174 175 assertTrue(map.size() == 0 && map.isEmpty(), 176 String.format("remove: map empty. size=%d", map.size())); 177 } 178 179 }