Redis哈希表的实现要点

哈希算法的选择

unsigned int dictIntHashFunction(unsigned int key)
{
key += ~(key << 15);
key ^=  (key >> 10);
key +=  (key << 3);
key ^=  (key >> 6);
key += ~(key << 11);
key ^=  (key >> 16);
return key;
}

murmur是 multiply and rotate的意思，因为算法的核心就是不断的乘和移位（x *= m; k ^= k >> r;）

unsigned int dictGenHashFunction(const void *key, int len) {
/* 'm' and 'r' are mixing constants generated offline.
They're not really 'magic', they just happen to work well.  */
uint32_t seed = dict_hash_function_seed;
const uint32_t m = 0x5bd1e995;
const int r = 24;

/* Initialize the hash to a 'random' value */
uint32_t h = seed ^ len;

/* Mix 4 bytes at a time into the hash */
const unsigned char *data = (const unsigned char *)key;

while(len >= 4) {
uint32_t k = *(uint32_t*)data;

k *= m;
k ^= k >> r;
k *= m;

h *= m;
h ^= k;

data += 4;
len -= 4;
}

/* Handle the last few bytes of the input array  */
switch(len) {
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0]; h *= m;
};

/* Do a few final mixes of the hash to ensure the last few
* bytes are well-incorporated. */
h ^= h >> 13;
h *= m;
h ^= h >> 15;

return (unsigned int)h;
}

1) 性能高，运算足够快；
2) 相邻的数据hash后分布广；即使输入的键是有规律的，算法仍然能给出一个很好的随机分布性；

rehash的触发条件：

value的存储

// 键
void *key;

// 值
union {
void *val;
uint64_t u64;
int64_t s64;
} v;

ref：
《Hash 函数概览》http://www.oschina.net/translate/state-of-hash-functions
《redis设计与实现》

Posted by: 大CC | 18NOV,2015

Github：大CC

posted @ 2015-11-18 21:31 大CC 阅读(...) 评论(...) 编辑 收藏