mirror of
https://github.com/ceph/ceph
synced 2024-12-23 11:54:11 +00:00
9213a23f14
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1138 29311d96-e01e-0410-9327-a35deaab8ce9
288 lines
7.1 KiB
C++
288 lines
7.1 KiB
C++
|
|
// 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 crush {
|
|
|
|
class Hash {
|
|
int seed;
|
|
|
|
public:
|
|
int get_seed() { return seed; }
|
|
void set_seed(int s) { seed = s; }
|
|
|
|
Hash(int s) {
|
|
unsigned int hash = 1315423911;
|
|
int x = 231232;
|
|
int y = 1232;
|
|
hashmix(s, x, hash);
|
|
hashmix(y, s, hash);
|
|
seed = s;
|
|
}
|
|
|
|
inline int operator()(int a) {
|
|
unsigned int hash = seed ^ a;
|
|
int b = a;
|
|
int x = 231232;
|
|
int y = 1232;
|
|
hashmix(b, x, hash);
|
|
hashmix(y, a, hash);
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
inline int operator()(int a, int b) {
|
|
unsigned int hash = seed ^ a ^ b;
|
|
int x = 231232;
|
|
int y = 1232;
|
|
hashmix(a, b, hash);
|
|
hashmix(x, a, hash);
|
|
hashmix(b, y, hash);
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
inline int operator()(int a, int b, int c) {
|
|
unsigned int hash = seed ^ a ^ b ^ c;
|
|
int x = 231232;
|
|
int y = 1232;
|
|
hashmix(a, b, hash);
|
|
hashmix(c, x, hash);
|
|
hashmix(y, a, hash);
|
|
hashmix(b, x, hash);
|
|
hashmix(y, c, hash);
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
inline int operator()(int a, int b, int c, int d) {
|
|
unsigned int hash = seed ^a ^ b ^ c ^ d;
|
|
int x = 231232;
|
|
int y = 1232;
|
|
hashmix(a, b, hash);
|
|
hashmix(c, d, hash);
|
|
hashmix(a, x, hash);
|
|
hashmix(y, b, hash);
|
|
hashmix(c, x, hash);
|
|
hashmix(y, d, hash);
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
inline int operator()(int a, int b, int c, int d, int e) {
|
|
unsigned int hash = seed ^ a ^ b ^ c ^ d ^ e;
|
|
int x = 231232;
|
|
int y = 1232;
|
|
hashmix(a, b, hash);
|
|
hashmix(c, d, hash);
|
|
hashmix(e, x, hash);
|
|
hashmix(y, a, hash);
|
|
hashmix(b, x, hash);
|
|
hashmix(y, c, hash);
|
|
hashmix(d, x, hash);
|
|
hashmix(y, e, hash);
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
//return myhash(a) ^ seed;
|
|
return myhash(a, seed);
|
|
}
|
|
int operator()(int a, int b) {
|
|
//return myhash( myhash(a) ^ myhash(b) ^ seed );
|
|
return myhash(a, b, seed);
|
|
}
|
|
int operator()(int a, int b, int c) {
|
|
//return myhash( myhash(a ^ seed) ^ myhash(b ^ seed) ^ myhash(c ^ seed) ^ seed );
|
|
return myhash(a, b, c, seed);
|
|
}
|
|
int operator()(int a, int b, int c, int d) {
|
|
//return myhash( myhash(a ^ seed) ^ myhash(b ^ seed) ^ myhash(c ^ seed) ^ myhash(d ^ seed) ^ seed );
|
|
return myhash(a, b, c, d, seed);
|
|
}
|
|
|
|
// ethan's rush hash?
|
|
if (0)
|
|
return (n ^ 0xdead1234) * (884811920 * 3 + 1);
|
|
|
|
if (1) {
|
|
|
|
// before
|
|
hash ^= ((hash << 5) + (n&255) + (hash >> 2));
|
|
hashmix(a, b, hash);
|
|
n = n >> 8;
|
|
hash ^= ((hash << 5) + (n&255) + (hash >> 2));
|
|
hashmix(a, b, hash);
|
|
n = n >> 8;
|
|
hash ^= ((hash << 5) + (n&255) + (hash >> 2));
|
|
hashmix(a, b, hash);
|
|
n = n >> 8;
|
|
hash ^= ((hash << 5) + (n&255) + (hash >> 2));
|
|
hashmix(a, b, hash);
|
|
n = n >> 8;
|
|
|
|
//return hash;
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
// JS
|
|
// a little better than RS
|
|
// + jenkin's mixing thing (which sucks on its own but helps tons here)
|
|
// best so far
|
|
if (1) {
|
|
unsigned int hash = 1315423911;
|
|
int a = 231232;
|
|
int b = 1232;
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
{
|
|
hash ^= ((hash << 5) + (n&255) + (hash >> 2));
|
|
hashmix(a, b, hash);
|
|
n = n >> 8;
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
|
|
// Robert jenkins' 96 bit mix
|
|
// sucks
|
|
if (0) {
|
|
int c = n;
|
|
int a = 12378912;
|
|
int b = 2982827;
|
|
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);
|
|
return c;
|
|
}
|
|
// robert jenkins 32-bit
|
|
// sucks
|
|
if (0) {
|
|
n += (n << 12);
|
|
n ^= (n >> 22);
|
|
n += (n << 4);
|
|
n ^= (n >> 9);
|
|
n += (n << 10);
|
|
n ^= (n >> 2);
|
|
n += (n << 7);
|
|
n ^= (n >> 12);
|
|
return n;
|
|
}
|
|
|
|
// djb2
|
|
if (0) {
|
|
unsigned int hash = 5381;
|
|
for (int i=0; i<4; i++) {
|
|
hash = ((hash << 5) + hash) + ((n&255) ^ 123);
|
|
n = n >> 8;
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
|
|
// SDBM
|
|
if (1) {
|
|
unsigned int hash = 0;
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
{
|
|
hash = (n&255) + (hash << 6) + (hash << 16) - hash;
|
|
n = n >> 8;
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
// PJW
|
|
// horrid
|
|
if (0) {
|
|
unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
|
|
unsigned int ThreeQuarters = (unsigned int)((BitsInUnsignedInt * 3) / 4);
|
|
unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt / 8);
|
|
unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
|
|
unsigned int hash = 0;
|
|
unsigned int test = 0;
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
{
|
|
hash = (hash << OneEighth) + (n&255);
|
|
|
|
if((test = hash & HighBits) != 0)
|
|
{
|
|
hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));
|
|
}
|
|
n = n >> 8;
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
// RS Hash function, from Robert Sedgwicks Algorithms in C book, w/ some changes.
|
|
if (0) {
|
|
unsigned int b = 378551;
|
|
unsigned int a = 63689;
|
|
unsigned int hash = 0;
|
|
|
|
for(unsigned int i=0; i<4; i++)
|
|
{
|
|
hash = hash * a + (n&0xff);
|
|
a = a * b;
|
|
n = n >> 8;
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
// DJB
|
|
// worse than rs
|
|
if (0) {
|
|
unsigned int hash = 5381;
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
{
|
|
hash = ((hash << 5) + hash) + (n&255);
|
|
n = n >> 8;
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
// AP
|
|
// even worse
|
|
if (1) {
|
|
unsigned int hash = 0;
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
{
|
|
hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (n&255) ^ (hash >> 3)) :
|
|
(~((hash << 11) ^ (n&255) ^ (hash >> 5)));
|
|
n = n >> 8;
|
|
}
|
|
|
|
return (hash & 0x7FFFFFFF);
|
|
}
|
|
|
|
|
|
#endif
|