]> mj.ucw.cz Git - libucw.git/blobdiff - lib/hashfunc.c
taken much faster implementation of Adler32 and put into a separate source-code
[libucw.git] / lib / hashfunc.c
index 631a0bbe16550f14a46c0884e77c43a002633ac8..ad6a6bdf9d0637acbfc76770308581e2f4a37ea0 100644 (file)
@@ -6,6 +6,9 @@
  *     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)];
@@ -34,24 +37,24 @@ hashfunc_init(void)
        }
 }
 
-static inline uns str_len_uns(uns x) CONST;
-
-static inline uns
+static inline uns CONST
 str_len_uns(uns x)
 {
-       const uns sub = ((uns) -1) / 0xff;
+       const uns sub = ~0U / 0xff;
        const uns and = sub * 0x80;
        uns a, i;
        byte *bytes;
-       a = (x ^ (x - sub)) & and;
+       a = ~x & (x - sub) & and;
        /* 
         * x_2 = x - 0x01010101;
-        * x_3 = x ^ x_2;
+        * x_3 = ~x & x_2;
         * a = x_3 & 0x80808080;
         *
-        * If none byte of x is in {0, 0x80}, then the highest bit of each byte
-        * of x_2 is the same as of x.  Hence x_3 has all these highest bits
-        * cleared.  If a == 0, then we are sure there is no zero byte in x.
+        * If all bytes of x are nonzero, then the highest bit of each byte of
+        * x_2 is lower or equal to the corresponding bit of x.  Hence x_3 has
+        * all these highest bits cleared (the target bit is set iff the source
+        * bit has changed from 0 to 1).  If a == 0, then we are sure there is
+        * no zero byte in x.
         */
        if (!a)
                return sizeof(uns);