X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Flinux%2Fhash.h;h=44a3b95f16c18a08fbc078de4718592fa7690538;hb=b2d5074d5d465930612c26de2ecabaf50024583d;hp=b80506bdd733ee181f202ddb6322529d42299d1b;hpb=b2409fb6a49d1f633a8fc488e48043da7d3fd6a7;p=pandora-kernel.git diff --git a/include/linux/hash.h b/include/linux/hash.h index b80506bdd733..44a3b95f16c1 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h @@ -31,10 +31,29 @@ #error Wordsize not 32 or 64 #endif +/* + * The above primes are actively bad for hashing, since they are + * too sparse. The 32-bit one is mostly ok, the 64-bit one causes + * real problems. Besides, the "prime" part is pointless for the + * multiplicative hash. + * + * Although a random odd number will do, it turns out that the golden + * ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice + * properties. + * + * These are the negative, (1 - phi) = (phi^2) = (3 - sqrt(5))/2. + * (See Knuth vol 3, section 6.4, exercise 9.) + */ +#define GOLDEN_RATIO_32 0x61C88647 +#define GOLDEN_RATIO_64 0x61C8864680B583EBull + static inline u64 hash_64(u64 val, unsigned int bits) { u64 hash = val; +#if BITS_PER_LONG == 64 + hash = hash * GOLDEN_RATIO_64; +#else /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ u64 n = hash; n <<= 18; @@ -49,6 +68,7 @@ static inline u64 hash_64(u64 val, unsigned int bits) hash += n; n <<= 2; hash += n; +#endif /* High bits are more random, so use them. */ return hash >> (64 - bits);