#include "cx/hash_key.h"
#include <string.h>
void cx_hash_murmur(CxHashKey *key) {
const unsigned char *data = key->data;
if (data ==
NULL) {
key->hash = 1574210520u;
return;
}
size_t len = key->len;
unsigned m = 0x5bd1e995;
unsigned r =
24;
unsigned h =
25 ^ len;
unsigned i =
0;
while (len >=
4) {
unsigned k = data[i +
0] & 0xFF;
k |= (data[i +
1] & 0xFF) <<
8;
k |= (data[i +
2] & 0xFF) <<
16;
k |= (data[i +
3] & 0xFF) <<
24;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
i +=
4;
len -=
4;
}
switch (len) {
case 3:
h ^= (data[i +
2] & 0xFF) <<
16;
__attribute__((__fallthrough__));
case 2:
h ^= (data[i +
1] & 0xFF) <<
8;
__attribute__((__fallthrough__));
case 1:
h ^= (data[i +
0] & 0xFF);
h *= m;
__attribute__((__fallthrough__));
default:
;
}
h ^= h >>
13;
h *= m;
h ^= h >>
15;
key->hash = h;
}
CxHashKey cx_hash_key_str(
const char *str) {
CxHashKey key;
key.data = str;
key.len = str ==
NULL ?
0 : strlen(str);
cx_hash_murmur(&key);
return key;
}
CxHashKey cx_hash_key_bytes(
const unsigned char *bytes,
size_t len
) {
CxHashKey key;
key.data = bytes;
key.len = len;
cx_hash_murmur(&key);
return key;
}
CxHashKey cx_hash_key(
const void *obj,
size_t len
) {
CxHashKey key;
key.data = obj;
key.len = len;
cx_hash_murmur(&key);
return key;
}