/* * Get a new random hash value. */ extern hash_t hash_new(void) { hash_t hash = seed_x; hash_t seed_y = SEED_Y; hash = hash_mix(hash, seed_y); hash_t inc = SEED_INC; hash_t seed_z = SEED_Z; hash = hash_mix(hash, seed_z); seed_x += inc; hash_t seed_w = SEED_W; hash = hash_mix(hash, seed_w); hash_t zero = HASH(0, 0); hash = hash_mix(hash, zero); return hash; }
/* Returns the hash of the 'n' 32-bit words at 'p', starting from 'basis'. * 'p' must be properly aligned. */ uint32_t hash_words(const uint32_t *p, size_t n, uint32_t basis) { uint32_t a, b, c; a = b = c = 0xdeadbeef + (((uint32_t) n) << 2) + basis; while (n > 3) { a += p[0]; b += p[1]; c += p[2]; hash_mix(&a, &b, &c); n -= 3; p += 3; } switch (n) { case 3: c += p[2]; /* fall through */ case 2: b += p[1]; /* fall through */ case 1: a += p[0]; hash_final(&a, &b, &c); /* fall through */ case 0: break; } return c; }
/* Returns the hash of the 'n' bytes at 'p', starting from 'basis'. */ uint32_t hash_bytes(const void *p_, size_t n, uint32_t basis) { const uint8_t *p = p_; uint32_t a, b, c; a = b = c = 0xdeadbeef + n + basis; while (n >= 12) { a += get_unaligned_u32((uint32_t *) p); b += get_unaligned_u32((uint32_t *) (p + 4)); c += get_unaligned_u32((uint32_t *) (p + 8)); hash_mix(&a, &b, &c); n -= 12; p += 12; } if (n) { uint32_t tmp[3]; tmp[0] = tmp[1] = tmp[2] = 0; memcpy(tmp, p, n); a += tmp[0]; b += tmp[1]; c += tmp[2]; hash_final(&a, &b, &c); } return c; }
static __inline u32_t makehash(u32_t p1, u64_t p2) { u32_t offlo = ex64lo(p2), offhi = ex64hi(p2), v = 0x12345678; hash_mix(p1, offlo, offhi); hash_final(offlo, offhi, v); return v % HASHSIZE; }