jdk/test/java/util/Map/Collisions.java
changeset 13805 29e474ceeddc
parent 13025 e070f58ad775
child 13811 7d2276f93d68
equal deleted inserted replaced
13804:443fd84a849a 13805:29e474ceeddc
    22  */
    22  */
    23 
    23 
    24 /*
    24 /*
    25  * @test
    25  * @test
    26  * @bug 7126277
    26  * @bug 7126277
       
    27  * @run main Collisions -shortrun
       
    28  * @run main Collisions -Djdk.map.althashing.threshold=0 -shortrun
    27  * @summary Ensure Maps behave well with lots of hashCode() collisions.
    29  * @summary Ensure Maps behave well with lots of hashCode() collisions.
    28  * @author Mike Duigou
    30  * @author Mike Duigou
    29  */
    31  */
    30 import java.util.*;
    32 import java.util.*;
    31 import java.util.concurrent.ConcurrentHashMap;
    33 import java.util.concurrent.ConcurrentHashMap;
    32 import java.util.concurrent.ConcurrentSkipListMap;
    34 import java.util.concurrent.ConcurrentSkipListMap;
    33 
    35 
    34 public class Collisions {
    36 public class Collisions {
    35 
    37 
       
    38     /**
       
    39      * Number of elements per map.
       
    40      */
       
    41     private static final int TEST_SIZE = 5000;
       
    42 
    36     final static class HashableInteger implements Comparable<HashableInteger> {
    43     final static class HashableInteger implements Comparable<HashableInteger> {
    37 
    44 
    38         final int value;
    45         final int value;
    39         final int hashmask; //yes duplication
    46         final int hashmask; //yes duplication
    40 
    47 
    62         @Override
    69         @Override
    63         public int compareTo(HashableInteger o) {
    70         public int compareTo(HashableInteger o) {
    64             return value - o.value;
    71             return value - o.value;
    65         }
    72         }
    66 
    73 
       
    74         @Override
    67         public String toString() {
    75         public String toString() {
    68             return Integer.toString(value);
    76             return Integer.toString(value);
    69         }
    77         }
    70     }
    78     }
    71     private static final int ITEMS = 5000;
    79 
    72     private static final Object KEYS[][];
    80     private static Object[][] makeTestData(int size) {
    73 
    81         HashableInteger UNIQUE_OBJECTS[] = new HashableInteger[size];
    74     static {
    82         HashableInteger COLLIDING_OBJECTS[] = new HashableInteger[size];
    75         HashableInteger UNIQUE_OBJECTS[] = new HashableInteger[ITEMS];
    83         String UNIQUE_STRINGS[] = new String[size];
    76         HashableInteger COLLIDING_OBJECTS[] = new HashableInteger[ITEMS];
    84         String COLLIDING_STRINGS[] = new String[size];
    77         String UNIQUE_STRINGS[] = new String[ITEMS];
    85 
    78         String COLLIDING_STRINGS[] = new String[ITEMS];
    86         for (int i = 0; i < size; i++) {
    79 
       
    80         for (int i = 0; i < ITEMS; i++) {
       
    81             UNIQUE_OBJECTS[i] = new HashableInteger(i, Integer.MAX_VALUE);
    87             UNIQUE_OBJECTS[i] = new HashableInteger(i, Integer.MAX_VALUE);
    82             COLLIDING_OBJECTS[i] = new HashableInteger(i, 10);
    88             COLLIDING_OBJECTS[i] = new HashableInteger(i, 10);
    83             UNIQUE_STRINGS[i] = unhash(i);
    89             UNIQUE_STRINGS[i] = unhash(i);
    84             COLLIDING_STRINGS[i] = (0 == i % 2)
    90             COLLIDING_STRINGS[i] = (0 == i % 2)
    85                     ? UNIQUE_STRINGS[i / 2]
    91                     ? UNIQUE_STRINGS[i / 2]
    86                     : "\u0000\u0000\u0000\u0000\u0000" + COLLIDING_STRINGS[i - 1];
    92                     : "\u0000\u0000\u0000\u0000\u0000" + COLLIDING_STRINGS[i - 1];
    87         }
    93         }
    88 
    94 
    89      KEYS = new Object[][] {
    95      return new Object[][] {
    90             new Object[]{"Unique Objects", UNIQUE_OBJECTS},
    96             new Object[]{"Unique Objects", UNIQUE_OBJECTS},
    91             new Object[]{"Colliding Objects", COLLIDING_OBJECTS},
    97             new Object[]{"Colliding Objects", COLLIDING_OBJECTS},
    92             new Object[]{"Unique Strings", UNIQUE_STRINGS},
    98             new Object[]{"Unique Strings", UNIQUE_STRINGS},
    93             new Object[]{"Colliding Strings", COLLIDING_STRINGS}
    99             new Object[]{"Colliding Strings", COLLIDING_STRINGS}
    94         };
   100         };
   130             partial.append((char) rem);
   136             partial.append((char) rem);
   131         }
   137         }
   132     }
   138     }
   133 
   139 
   134     private static void realMain(String[] args) throws Throwable {
   140     private static void realMain(String[] args) throws Throwable {
   135         for (Object[] keys_desc : KEYS) {
   141         boolean shortRun = args.length > 0 && args[0].equals("-shortrun");
   136             Map<Object, Object>[] MAPS = (Map<Object, Object>[]) new Map[]{
   142 
       
   143         Object[][] mapKeys = makeTestData(shortRun ? (TEST_SIZE / 2) : TEST_SIZE);
       
   144 
       
   145         // loop through data sets
       
   146         for (Object[] keys_desc : mapKeys) {
       
   147             Map<Object, Object>[] maps = (Map<Object, Object>[]) new Map[]{
       
   148                         new HashMap<>(),
   137                         new Hashtable<>(),
   149                         new Hashtable<>(),
   138                         new HashMap<>(),
       
   139                         new IdentityHashMap<>(),
   150                         new IdentityHashMap<>(),
   140                         new LinkedHashMap<>(),
   151                         new LinkedHashMap<>(),
       
   152                         new TreeMap<>(),
       
   153                         new WeakHashMap<>(),
   141                         new ConcurrentHashMap<>(),
   154                         new ConcurrentHashMap<>(),
   142                         new WeakHashMap<>(),
       
   143                         new TreeMap<>(),
       
   144                         new ConcurrentSkipListMap<>()
   155                         new ConcurrentSkipListMap<>()
   145                     };
   156                     };
   146 
   157 
   147             for (Map<Object, Object> map : MAPS) {
   158             // for each map type.
       
   159             for (Map<Object, Object> map : maps) {
   148                 String desc = (String) keys_desc[0];
   160                 String desc = (String) keys_desc[0];
   149                 Object[] keys = (Object[]) keys_desc[1];
   161                 Object[] keys = (Object[]) keys_desc[1];
   150                 try {
   162                 try {
   151                 testMap(map, desc, keys);
   163                     testMap(map, desc, keys);
   152                 } catch(Exception all) {
   164                 } catch(Exception all) {
   153                     unexpected("Failed for " + map.getClass().getName() + " with " + desc, all);
   165                     unexpected("Failed for " + map.getClass().getName() + " with " + desc, all);
   154                 }
   166                 }
   155             }
   167             }
   156         }
   168         }
   395             fail(x + " not equal to " + y);
   407             fail(x + " not equal to " + y);
   396         }
   408         }
   397     }
   409     }
   398 
   410 
   399     public static void main(String[] args) throws Throwable {
   411     public static void main(String[] args) throws Throwable {
   400         Thread.currentThread().setName("Collisions");
   412         Thread.currentThread().setName(Collisions.class.getName());
   401 //        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
   413 //        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
   402         try {
   414         try {
   403             realMain(args);
   415             realMain(args);
   404         } catch (Throwable t) {
   416         } catch (Throwable t) {
   405             unexpected(t);
   417             unexpected(t);