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