]> mj.ucw.cz Git - libucw.git/blobdiff - lib/hashfunc.c
Merge with git+ssh://cvs.ucw.cz/projects/sherlock/GIT/sherlock.git#dev-make
[libucw.git] / lib / hashfunc.c
index 2f951c6977ab5725e49281fa5135bfcb4d9d4592..8fca5f4139254cd211bd71eb9a4edb04fe4d90aa 100644 (file)
@@ -1,11 +1,14 @@
 /*
- *     Hyper-super-meta-alt-control-shift extra fast str_len() and hash_*()
- *     routines
+ *     UCW Library -- Hyper-super-meta-alt-control-shift extra fast
+ *     str_len() and hash_*() routines
  *
  *     It is always at least as fast as the classical strlen() routine and for
  *     strings longer than 100 characters, it is substantially faster.
  *
  *     (c) 2002, Robert Spalek <robert@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
  */
 
 #include "lib/lib.h"
@@ -14,7 +17,7 @@
 
 /* The number of bits the hash in the function hash_*() is rotated by after
  * every pass.  It should be prime with the word size.  */
-#define        SHIFT_BITS      5
+#define        SHIFT_BITS      7
 
 /* A bit-mask which clears higher bytes than a given threshold.  */
 static uns mask_higher_bits[sizeof(uns)];
@@ -42,7 +45,7 @@ str_len_uns(uns x)
        uns a, i;
        byte *bytes;
        a = ~x & (x - sub) & and;
-       /* 
+       /*
         * x_2 = x - 0x01010101;
         * x_3 = ~x & x_2;
         * a = x_3 & 0x80808080;
@@ -61,7 +64,7 @@ str_len_uns(uns x)
 }
 
 inline uns
-str_len_aligned(const byte *str)
+str_len_aligned(const char *str)
 {
        const uns *u = (const uns *) str;
        uns len = 0;
@@ -75,7 +78,7 @@ str_len_aligned(const byte *str)
 }
 
 inline uns
-hash_string_aligned(const byte *str)
+hash_string_aligned(const char *str)
 {
        const uns *u = (const uns *) str;
        uns hash = 0;
@@ -109,7 +112,7 @@ hash_block_aligned(const byte *str, uns len)
 
 #ifndef        CPU_ALLOW_UNALIGNED
 uns
-str_len(const byte *str)
+str_len(const char *str)
 {
        uns shift = UNALIGNED_PART(str, uns);
        if (!shift)
@@ -126,11 +129,12 @@ str_len(const byte *str)
 }
 
 uns
-hash_string(const byte *str)
+hash_string(const char *str)
 {
-       uns shift = UNALIGNED_PART(str, uns);
+       const byte *s = str;
+       uns shift = UNALIGNED_PART(s, uns);
        if (!shift)
-               return hash_string_aligned(str);
+               return hash_string_aligned(s);
        else
        {
                uns hash = 0;
@@ -146,9 +150,9 @@ hash_string(const byte *str)
 #endif
                        if (!modulo)
                                hash = ROL(hash, SHIFT_BITS);
-                       if (!str[i])
+                       if (!s[i])
                                break;
-                       hash ^= str[i] << (shift * 8);
+                       hash ^= s[i] << (shift * 8);
                }
                return hash;
        }
@@ -185,8 +189,9 @@ hash_block(const byte *str, uns len)
 #endif
 
 uns
-hash_string_nocase(const byte *str)
+hash_string_nocase(const char *str)
 {
+       const byte *s = str;
        uns hash = 0;
        uns i;
        for (i=0; ; i++)
@@ -200,9 +205,9 @@ hash_string_nocase(const byte *str)
 #endif
                if (!modulo)
                        hash = ROL(hash, SHIFT_BITS);
-               if (!str[i])
+               if (!s[i])
                        break;
-               hash ^= Cupcase(str[i]) << (shift * 8);
+               hash ^= Cupcase(s[i]) << (shift * 8);
        }
        return hash;
 }