2013-10-30 03:30:51 +00:00
|
|
|
/*
|
|
|
|
* Hash function implementation
|
|
|
|
*
|
|
|
|
* See mailing list thread on "Consistent hashing alternative to sdbm"
|
|
|
|
* http://marc.info/?l=haproxy&m=138213693909219
|
|
|
|
*
|
|
|
|
* Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version
|
|
|
|
* 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <common/hash.h>
|
|
|
|
|
|
|
|
|
2014-07-08 15:51:03 +00:00
|
|
|
unsigned int hash_wt6(const char *key, int len)
|
2013-11-14 13:30:35 +00:00
|
|
|
{
|
|
|
|
unsigned h0 = 0xa53c965aUL;
|
|
|
|
unsigned h1 = 0x5ca6953aUL;
|
|
|
|
unsigned step0 = 6;
|
|
|
|
unsigned step1 = 18;
|
|
|
|
|
|
|
|
for (; len > 0; len--) {
|
|
|
|
unsigned int t;
|
|
|
|
|
|
|
|
t = ((unsigned int)*key);
|
|
|
|
key++;
|
|
|
|
|
|
|
|
h0 = ~(h0 ^ t);
|
|
|
|
h1 = ~(h1 + t);
|
|
|
|
|
|
|
|
t = (h1 << step0) | (h1 >> (32-step0));
|
|
|
|
h1 = (h0 << step1) | (h0 >> (32-step1));
|
|
|
|
h0 = t;
|
|
|
|
|
|
|
|
t = ((h0 >> 16) ^ h1) & 0xffff;
|
|
|
|
step0 = t & 0x1F;
|
|
|
|
step1 = t >> 11;
|
|
|
|
}
|
|
|
|
return h0 ^ h1;
|
|
|
|
}
|
|
|
|
|
2014-07-08 15:51:03 +00:00
|
|
|
unsigned int hash_djb2(const char *key, int len)
|
2013-10-30 03:30:51 +00:00
|
|
|
{
|
2014-07-08 15:51:03 +00:00
|
|
|
unsigned int hash = 5381;
|
2013-10-30 03:30:51 +00:00
|
|
|
|
|
|
|
/* the hash unrolled eight times */
|
|
|
|
for (; len >= 8; len -= 8) {
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
hash = ((hash << 5) + hash) + *key++;
|
|
|
|
}
|
|
|
|
switch (len) {
|
|
|
|
case 7: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
|
|
|
|
case 6: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
|
|
|
|
case 5: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
|
|
|
|
case 4: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
|
|
|
|
case 3: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
|
|
|
|
case 2: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
|
|
|
|
case 1: hash = ((hash << 5) + hash) + *key++; break;
|
|
|
|
default: /* case 0: */ break;
|
|
|
|
}
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2014-07-08 15:51:03 +00:00
|
|
|
unsigned int hash_sdbm(const char *key, int len)
|
2013-10-30 03:30:51 +00:00
|
|
|
{
|
2014-07-08 15:51:03 +00:00
|
|
|
unsigned int hash = 0;
|
2013-10-30 03:30:51 +00:00
|
|
|
int c;
|
|
|
|
|
|
|
|
while (len--) {
|
|
|
|
c = *key++;
|
|
|
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
|