博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
REDIS源码中一些值得学习的技术细节02
阅读量:5097 次
发布时间:2019-06-13

本文共 2408 字,大约阅读时间需要 8 分钟。

Redis中散列函数的实现:

Redis针对整数key和字符串key,采用了不同的散列函数

对于整数key,redis使用了 Thomas Wang的 32 bit Mix Function,实现了dict.c/dictIntHashFunction函数:

1 /* Thomas Wang's 32 bit Mix Function */ 2 unsigned int dictIntHashFunction(unsigned int key) 3 { 4     key += ~(key << 15); 5     key ^=  (key >> 10); 6     key +=  (key << 3); 7     key ^=  (key >> 6); 8     key += ~(key << 11); 9     key ^=  (key >> 16);10     return key;11 }

这段代码的妙处我还没来得及仔细研究,等研究好了会在这里补上,不过找到了两个初看还不错的链接:

首先是Thomas Wang大神本人的链接:

http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm

再者是他人根据上面链接和其他资料写的总结

http://blog.csdn.net/jasper_xulei/article/details/18364313

 

对于字符串形式的key,redis使用了MurmurHash2算法和djb算法:

MurmurHash2算法对于key是大小写敏感的,而且在大端机器和小端机器上生成结果不一致

redis的dict.c/dictGenHashFunction是MurmurHash2算法的C语言实现:

1 unsigned int dictGenHashFunction(const void *key, int len) { 2     /* 'm' and 'r' are mixing constants generated offline. 3      They're not really 'magic', they just happen to work well.  */ 4     uint32_t seed = dict_hash_function_seed; 5     const uint32_t m = 0x5bd1e995; 6     const int r = 24; 7  8     /* Initialize the hash to a 'random' value */ 9     uint32_t h = seed ^ len;10 11     /* Mix 4 bytes at a time into the hash */12     const unsigned char *data = (const unsigned char *)key;13 14     while(len >= 4) {15         uint32_t k = *(uint32_t*)data;16 17         k *= m;18         k ^= k >> r;19         k *= m;20 21         h *= m;22         h ^= k;23 24         data += 4;25         len -= 4;26     }27 28     /* Handle the last few bytes of the input array  */29     switch(len) {30     case 3: h ^= data[2] << 16;31     case 2: h ^= data[1] << 8;32     case 1: h ^= data[0]; h *= m;33     };34 35     /* Do a few final mixes of the hash to ensure the last few36      * bytes are well-incorporated. */37     h ^= h >> 13;38     h *= m;39     h ^= h >> 15;40 41     return (unsigned int)h;42 }

而redis则借助djb函数实现了不区分大小写的散列函数dict.c/dictGenCaseHashFunction:

1 unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {2     unsigned int hash = (unsigned int)dict_hash_function_seed;3 4     while (len--)5         hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */6     return hash;7 }

以上三个散列函数(dictIntHashFunction, dictIntHashFunction, dictGenCaseHashFunction)分别用在了redis的不同地方,用以实现了不同场合下的散列需求,接下来的文章将会详细介绍。

 

 

 

转载于:https://www.cnblogs.com/viggoxskingdom/p/5183659.html

你可能感兴趣的文章
冒泡排序, 使用最低票价.---双重循环,一重移动次数.二重移动
查看>>
1go基本语法
查看>>
C与C艹的内存管理方式
查看>>
[LintCode] 最小路径和
查看>>
S-GPRS车辆监控方案-转载
查看>>
给互联网创业公司的8个建议
查看>>
20160115小记
查看>>
hdu 2526
查看>>
那些常用的git工具
查看>>
join()方法之我见
查看>>
希尔shell排序——java实现
查看>>
webService学习1----WSDL
查看>>
评估分类器性能的度量,像混淆矩阵、ROC、AUC等
查看>>
Scala - Spark Lambda“goesto“ => 分析
查看>>
mysql TIMESTAMPDIFF
查看>>
win7下docker环境搭建nginx+php-fpm+easyswoole+lavarel+mysql开发环境
查看>>
通过cmd查看环境变量名对应的环境变量值
查看>>
Python: 利用Python进行数据分析 学习记录
查看>>
python 零基础学习之路-06 常用模块
查看>>
[Lintcode]165. Merge Two Sorted Lists/[Leetcode]21. Merge Two Sorted Lists
查看>>