Bug 56297

Summary: Attempted optimisation does not (improve performance)
Product: Tomcat Connectors Reporter: Thomas Schodt <apache>
Component: mod_jkAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: enhancement    
Priority: P2    
Version: 1.2.37   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Thomas Schodt 2014-03-21 12:15:52 UTC
Added Nov-2004 in JK 1.2.7 the COMPUTE_KEY_CHECKSUM macro 
is an attempt to allow us to check if we can skip a strcmp() invocation
but the key generated is always the same 
as all 'names' in mod_jk start with the same four characters ('work' - from 'worker.') so it does not improve performance.

http://svn.apache.org/viewvc?view=revision&revision=299957

It can be changed to a digest to get the desired performance gain.
Comment 1 Thomas Schodt 2014-03-21 12:22:26 UTC
Patch tested on linux.

$ svn diff jk_map.c
Index: jk_map.c
===================================================================
--- jk_map.c    (revision 1579918)
+++ jk_map.c    (working copy)
@@ -36,8 +36,8 @@
 #define JK_MAP_REFERENCE    (".reference")
 #define JK_MAP_REFERENCE_SZ (strlen(JK_MAP_REFERENCE))

-/* Compute the "checksum" for a key, consisting of the first
- * 4 bytes, packed into an int.
+/* Compute the "checksum" for a key, consisting of
+ * a digest of the string (same as java hashcode).
  * This checksum allows us to do a single integer
  * comparison as a fast check to determine whether we can
  * skip a strcmp
@@ -45,23 +45,13 @@
 #define COMPUTE_KEY_CHECKSUM(key, checksum)    \
 {                                              \
     const char *k = (key);                     \
-    unsigned int c = (unsigned int)*k;         \
-    (checksum) = c;                            \
-    (checksum) <<= 8;                          \
-    if (c) {                                   \
-        c = (unsigned int)*++k;                \
-        checksum |= c;                         \
+    (checksum) = 0;                            \
+    unsigned int c = (unsigned int)*k++;       \
+    while(c) {                                 \
+        (checksum) *= 31;                      \
+        (checksum) += c;                       \
+        c = (unsigned int)*k++;                \
     }                                          \
-    (checksum) <<= 8;                          \
-    if (c) {                                   \
-        c = (unsigned int)*++k;                \
-        checksum |= c;                         \
-    }                                          \
-    (checksum) <<= 8;                          \
-    if (c) {                                   \
-        c = (unsigned int)*++k;                \
-        checksum |= c;                         \
-    }                                          \
 }

 static volatile int global_map_id = 0;
Comment 2 Rainer Jung 2014-03-31 19:07:15 UTC
Thanks for the suggestion. I have taken a very similar code from the APR libs.
Fixed in r1583403. Will be part of 1.2.40.
Would be nice if you could give that change a try.