diff -urN linux-2.4.17-rc2-virgin/include/linux/dcache.h linux-2.4.17-rc2-wli2/include/linux/dcache.h --- linux-2.4.17-rc2-virgin/include/linux/dcache.h Tue Dec 18 23:18:03 2001 +++ linux-2.4.17-rc2-wli2/include/linux/dcache.h Thu Dec 20 18:55:13 2001 @@ -36,17 +36,58 @@ }; extern struct dentry_stat_t dentry_stat; -/* Name hashing routines. Initial hash value */ -/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ -#define init_name_hash() 0 +/* + * Fowler, Noll, & Vo hash function + * -- wli + */ + +/* + * Initial hash value for Fowler, Noll, & Vo hash function. + * FreeBSD appears to use 33554467UL decimal / 0x2000023UL hex. + * Sources I see elsewhere (Noll's webpage) describe using an offset + * basis of 2166136261UL decimal / 0x811C9DC5UL hex. + * -- wli + */ +#define init_name_hash() 0x811C9DC5UL -/* partial hash update function. Assume roughly 4 bits per character */ -static __inline__ unsigned long partial_name_hash(unsigned long c, unsigned long prevhash) +/* + * This is a multiplicative hash function using the prime 16777619 + * The Fowler, Noll, and Vo hash function is rated the best in + * string hashing benchmarks published on gcc-patches and NetBSD + * mailing lists. + * -- wli + */ +static __inline__ unsigned long partial_name_hash(unsigned long c, + unsigned long prevhash) { - return (prevhash + (c << 4) + (c >> 4)) * 11; + /* + * A multiplicative definition would be: + * --wli + */ + return (prevhash * 0x01000193UL) ^ c; + + /* + * If I were to get overcomplicated, I would decode things + * for each bit of 0x01000193UL and then expand to the shift + * and add operations explicitly in order to avoid reliance on + * the compiler for this. + * The register pressure generated by this may not be a win + * on i386 vs. actual multiplication, but results remain + * to be seen. + * + * prevhash += (prevhash << 24) + * + (prevhash << 8) + * + (prevhash << 7) + * + (prevhash << 4) + * + (prevhash << 1); + * return prevhash ^ c; + */ } -/* Finally: cut down the number of bits to a int value (and try to avoid losing bits) */ +/* + * Finally: cut down the number of bits to a int value (and try to + * avoid losing bits) + */ static __inline__ unsigned long end_name_hash(unsigned long hash) { return (unsigned int) hash;