X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fhashfunc.c;h=ad6a6bdf9d0637acbfc76770308581e2f4a37ea0;hb=0d56b467cc2184f00a4e390f95596704d819dfa3;hp=631a0bbe16550f14a46c0884e77c43a002633ac8;hpb=e1980ce3bfe2bf0d46bcc6e42fc4f1f35d541fe2;p=libucw.git diff --git a/lib/hashfunc.c b/lib/hashfunc.c index 631a0bbe..ad6a6bdf 100644 --- a/lib/hashfunc.c +++ b/lib/hashfunc.c @@ -6,6 +6,9 @@ * strings longer than 100 characters, it is substantially faster. * * (c) 2002, Robert Spalek + * + * 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);