jdk/src/share/classes/java/util/WeakHashMap.java
changeset 17939 bd750ec19d82
parent 17168 b7d3500f2516
child 17949 6c33d8f2601e
equal deleted inserted replaced
17938:af1b01dfea42 17939:bd750ec19d82
   185      *
   185      *
   186      * @see ConcurrentModificationException
   186      * @see ConcurrentModificationException
   187      */
   187      */
   188     int modCount;
   188     int modCount;
   189 
   189 
       
   190     private static class Holder {
       
   191         static final boolean USE_HASHSEED;
       
   192 
       
   193         static {
       
   194             String hashSeedProp = java.security.AccessController.doPrivileged(
       
   195                     new sun.security.action.GetPropertyAction(
       
   196                         "jdk.map.useRandomSeed"));
       
   197             boolean localBool = (null != hashSeedProp)
       
   198                     ? Boolean.parseBoolean(hashSeedProp) : false;
       
   199             USE_HASHSEED = localBool;
       
   200         }
       
   201     }
       
   202 
   190     /**
   203     /**
   191      * A randomizing value associated with this instance that is applied to
   204      * A randomizing value associated with this instance that is applied to
   192      * hash code of keys to make hash collisions harder to find.
   205      * hash code of keys to make hash collisions harder to find.
   193      */
   206      *
   194     transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this);
   207      * Non-final so it can be set lazily, but be sure not to set more than once.
       
   208      */
       
   209     transient int hashSeed;
       
   210 
       
   211     /**
       
   212      * Initialize the hashing mask value.
       
   213      */
       
   214     final void initHashSeed() {
       
   215         if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
       
   216             // Do not set hashSeed more than once!
       
   217             // assert hashSeed == 0;
       
   218             hashSeed = sun.misc.Hashing.randomHashSeed(this);
       
   219         }
       
   220     }
   195 
   221 
   196     @SuppressWarnings("unchecked")
   222     @SuppressWarnings("unchecked")
   197     private Entry<K,V>[] newTable(int n) {
   223     private Entry<K,V>[] newTable(int n) {
   198         return (Entry<K,V>[]) new Entry<?,?>[n];
   224         return (Entry<K,V>[]) new Entry<?,?>[n];
   199     }
   225     }
   221         while (capacity < initialCapacity)
   247         while (capacity < initialCapacity)
   222             capacity <<= 1;
   248             capacity <<= 1;
   223         table = newTable(capacity);
   249         table = newTable(capacity);
   224         this.loadFactor = loadFactor;
   250         this.loadFactor = loadFactor;
   225         threshold = (int)(capacity * loadFactor);
   251         threshold = (int)(capacity * loadFactor);
       
   252         initHashSeed();
   226     }
   253     }
   227 
   254 
   228     /**
   255     /**
   229      * Constructs a new, empty <tt>WeakHashMap</tt> with the given initial
   256      * Constructs a new, empty <tt>WeakHashMap</tt> with the given initial
   230      * capacity and the default load factor (0.75).
   257      * capacity and the default load factor (0.75).
   296      * critical because HashMap uses power-of-two length hash tables, that
   323      * critical because HashMap uses power-of-two length hash tables, that
   297      * otherwise encounter collisions for hashCodes that do not differ
   324      * otherwise encounter collisions for hashCodes that do not differ
   298      * in lower bits.
   325      * in lower bits.
   299      */
   326      */
   300     final int hash(Object k) {
   327     final int hash(Object k) {
   301         if (k instanceof String) {
   328         int h = hashSeed ^ k.hashCode();
   302             return ((String) k).hash32();
       
   303         }
       
   304         int  h = hashSeed ^ k.hashCode();
       
   305 
   329 
   306         // This function ensures that hashCodes that differ only by
   330         // This function ensures that hashCodes that differ only by
   307         // constant multiples at each bit position have a bounded
   331         // constant multiples at each bit position have a bounded
   308         // number of collisions (approximately 8 at default load factor).
   332         // number of collisions (approximately 8 at default load factor).
   309         h ^= (h >>> 20) ^ (h >>> 12);
   333         h ^= (h >>> 20) ^ (h >>> 12);