X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fhashfunc.c;h=8fca5f4139254cd211bd71eb9a4edb04fe4d90aa;hb=029a7f6703b0a0a102f7dff6c25ff1d419d75610;hp=2f951c6977ab5725e49281fa5135bfcb4d9d4592;hpb=e46742a23442319c5fa3106847b72c28cf1103ea;p=libucw.git diff --git a/lib/hashfunc.c b/lib/hashfunc.c index 2f951c69..8fca5f41 100644 --- a/lib/hashfunc.c +++ b/lib/hashfunc.c @@ -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 + * + * 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; }