diff options
Diffstat (limited to 'src/include/hash.h')
-rw-r--r-- | src/include/hash.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/include/hash.h b/src/include/hash.h new file mode 100644 index 000000000..2ab95448b --- /dev/null +++ b/src/include/hash.h @@ -0,0 +1,64 @@ +#ifndef CEPH_HASH_H +#define CEPH_HASH_H + +#include "acconfig.h" + +// Robert Jenkins' function for mixing 32-bit values +// http://burtleburtle.net/bob/hash/evahash.html +// a, b = random bits, c = input and output + +#define hashmix(a,b,c) \ + a=a-b; a=a-c; a=a^(c>>13); \ + b=b-c; b=b-a; b=b^(a<<8); \ + c=c-a; c=c-b; c=c^(b>>13); \ + a=a-b; a=a-c; a=a^(c>>12); \ + b=b-c; b=b-a; b=b^(a<<16); \ + c=c-a; c=c-b; c=c^(b>>5); \ + a=a-b; a=a-c; a=a^(c>>3); \ + b=b-c; b=b-a; b=b^(a<<10); \ + c=c-a; c=c-b; c=c^(b>>15); + + +//namespace ceph { + +template <class _Key> struct rjhash { }; + +inline uint64_t rjhash64(uint64_t key) { + key = (~key) + (key << 21); // key = (key << 21) - key - 1; + key = key ^ (key >> 24); + key = (key + (key << 3)) + (key << 8); // key * 265 + key = key ^ (key >> 14); + key = (key + (key << 2)) + (key << 4); // key * 21 + key = key ^ (key >> 28); + key = key + (key << 31); + return key; +} + +inline uint32_t rjhash32(uint32_t a) { + a = (a+0x7ed55d16) + (a<<12); + a = (a^0xc761c23c) ^ (a>>19); + a = (a+0x165667b1) + (a<<5); + a = (a+0xd3a2646c) ^ (a<<9); + a = (a+0xfd7046c5) + (a<<3); + a = (a^0xb55a4f09) ^ (a>>16); + return a; +} + + +template<> struct rjhash<uint32_t> { + inline size_t operator()(const uint32_t x) const { + return rjhash32(x); + } +}; + +template<> struct rjhash<uint64_t> { + inline size_t operator()(const uint64_t x) const { + return rjhash64(x); + } +}; + +//} + + + +#endif |