* to compute statistic buckets, in that it's fast and reasonably distributed
* thanks to mixing the bits via a multiplication by a prime number and using
* the middle bits on 64-bit platforms or remixing the topmost with lowest ones
- * on 32-bit. It provides ~2491 unique values (~1354 non-colliding) for 2^12
- * valid pointers at 12 bits, ~1454 (~941 non-colliding) for 2^11 valid ptrs
- * at 11 bits, ~707 (~434 non-colliding) for 2^10 valid ptrs at 10 bits, ~347
- * (212 non colliding) for 2^9 valid ptrs at 9 bits, and 165/99 for 2^8 ptrs
- * at 8 bits, hence 1-1/e and 1/e respectively. It must be inlined so that
- * <bits> is always a compile-time constant. It supports output sizes from 0
- * to 32 bits.
+ * on 32-bit. The distribution is smooth enough for the hash to provide on
+ * average 1/e non-colliding entries per input, and use on average 1-1/e
+ * entries total. Thus for example hashing 1024 random valid pointers will
+ * result on average in ~647 distinct keys, 377 of which are unique. It was
+ * carefully selected to deliver optimal distribution for low bit counts so
+ * that hashing on 2,3,4 or 5 bits delivers good results.
*/
static forceinline uint ptr_hash(const void *p, const int bits)
{
if (!bits)
return 0;
- x *= 0xc1da9653U;
+ x *= 0xacd1be85U;
if (sizeof(long) == 4)
x ^= x >> 32;
else
if (!bits)
return 0;
- x *= 0xc1da9653U;
- y *= 0x96531cadU;
+ x *= 0xacd1be85U;
+ y *= 0x9d28e4e9U;
x ^= y;
if (sizeof(long) == 4)
x ^= x >> 32;