src/share/classes/java/lang/String.java

Print this page
rev 5380 : 7126277: Alternative hashing implementation

@@ -23,11 +23,10 @@
  * questions.
  */
 
 package java.lang;
 
-import java.io.ObjectStreamClass;
 import java.io.ObjectStreamField;
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;

@@ -35,10 +34,11 @@
 import java.util.Formatter;
 import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
+import sun.misc.Hashing;
 
 /**
  * The {@code String} class represents character strings. All
  * string literals in Java programs, such as {@code "abc"}, are
  * implemented as instances of this class.

@@ -106,11 +106,11 @@
  * @see     java.nio.charset.Charset
  * @since   JDK1.0
  */
 
 public final class String
-    implements java.io.Serializable, Comparable<String>, CharSequence
+    implements java.io.Serializable, Comparable<String>, CharSequence, Hashable32
 {
     /** The value is used for character storage. */
     private final char value[];
 
     /** The offset is the first index of the storage that is used. */

@@ -3075,6 +3075,45 @@
      * @return  a string that has the same contents as this string, but is
      *          guaranteed to be from a pool of unique strings.
      */
     public native String intern();
 
+    /**
+     * Seed value used for each alternative hash calculated.
+     */
+    private static final int HASHING_SEED;
+    
+    static {
+        // ??? Stronger random source? (Random/SecureRandom is not available)
+        HASHING_SEED = System.identityHashCode(String.class)
+                ^ System.identityHashCode(System.class)
+                ^ System.identityHashCode(Thread.currentThread())
+                ^ (int) (System.currentTimeMillis() >>> 2) // resolution is poor
+                ^ (int) (System.nanoTime() >>> 5); // resolution is poor
+    }
+
+    /**
+     * Cached value of the hashing algorithm result
+     */
+    private transient int hash32 = 0;
+
+    /**
+     * {@inheritDoc}
+     * 
+     * <p/>
+     * The hash value will never be zero.
+     */
+    public int hash32() {
+        int h = hash32;
+        if (0 == h) {
+           // harmless data race on hash32 here.            
+           h = Hashing.murmur3_32(HASHING_SEED, value, offset, count);
+           
+           // ensure result is not zero to avoid recalcing
+           h = (0 != h) ? h : 1;
+           
+           hash32 = h;
+        }
+
+        return h;
+    }
 }