You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2009/01/06 13:51:24 UTC

svn commit: r731929 - in /db/derby/code/trunk/java/engine/org/apache/derby/iapi/types: SQLBinary.java SQLChar.java

Author: kahatlen
Date: Tue Jan  6 04:51:22 2009
New Revision: 731929

URL: http://svn.apache.org/viewvc?rev=731929&view=rev
Log:
DERBY-3981: Improve distribution of hash codes in SQLBinary and SQLChar

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java?rev=731929&r1=731928&r2=731929&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBinary.java Tue Jan  6 04:51:22 2009
@@ -1088,17 +1088,19 @@
 			return 0;
 		}
 
-		/* Hash code is simply the sum of all of the bytes */
+		// Hash code should ignore trailing PAD bytes.
 		byte[] bytes = dataValue;
-		int hashcode = 0;
+        int lastNonPadByte = bytes.length - 1;
+        while (lastNonPadByte >= 0 && bytes[lastNonPadByte] == PAD) {
+            lastNonPadByte--;
+        }
 
-		// Build the hash code
-		for (int index = 0 ; index < bytes.length; index++)
-		{
-			byte bv = bytes[index];
-			if (bv != SQLBinary.PAD)
-				hashcode += bytes[index];
-		}
+        // Build the hash code in a way similar to String.hashCode() and
+        // SQLChar.hashCode()
+        int hashcode = 0;
+        for (int i = 0; i <= lastNonPadByte; i++) {
+            hashcode = hashcode * 31 + bytes[i];
+        }
 
 		return hashcode;
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java?rev=731929&r1=731928&r2=731929&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java Tue Jan  6 04:51:22 2009
@@ -113,6 +113,11 @@
      */
 
     /**
+     * The pad character (space).
+     */
+    private static final char PAD = '\u0020';
+
+    /**
      * threshold, that decides when we return space back to the VM
      * see getString() where it is used
      */
@@ -2681,27 +2686,25 @@
          * since it will create a new object, so here's what we do:
          *      o  Walk from the right until we've found the 1st
          *         non-blank character.
-         *      o  Add up the characters from that character to the 1st in
-         *         the string and return that as the hash code.
+         *      o  Calculate the hash code based on the characters from the
+         *         start up to the first non-blank character from the right.
          */
-        int index;
-        int hashcode = 0;
 
         // value will have been set by the getString() above
         String lvalue = value;
 
         // Find 1st non-blank from the right
-        for (index = lvalue.length() - 1; 
-             index >= 0 && lvalue.charAt(index) == ' '; 
-             index--)
-        {
-            ;
+        int lastNonPadChar = lvalue.length() - 1;
+        while (lastNonPadChar >= 0 && lvalue.charAt(lastNonPadChar) == PAD) {
+            lastNonPadChar--;
         }
 
-        // Build the hash code
-        for ( ; index >= 0; index--)
-        {
-            hashcode += lvalue.charAt(index);
+        // Build the hash code. It should be identical to what we get from
+        // lvalue.substring(0, lastNonPadChar+1).hashCode(), but it should be
+        // cheaper this way since we don't allocate a new string.
+        int hashcode = 0;
+        for (int i = 0; i <= lastNonPadChar; i++) {
+            hashcode = hashcode * 31 + lvalue.charAt(i);
         }
 
         return hashcode;