REDIS源码中一些值得学习的技术细节02
Redis中散列函数的实现:
Redis针对整数key和字符串key,采用了不同的散列函数
对于整数key,redis使用了 Thomas Wang的 32 bit Mix Function,实现了dict.c/dictIntHashFunction函数:
/* Thomas Wang's 32 bit Mix Function */
unsigned int dictIntHashFunction(unsigned int key)
{
key += ~(key << );
key ^= (key >> );
key += (key << );
key ^= (key >> );
key += ~(key << );
key ^= (key >> );
return key;
}
这段代码的妙处我还没来得及仔细研究,等研究好了会在这里补上,不过找到了两个初看还不错的链接:
首先是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语言实现:
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 = ; /* 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 >= ) {
uint32_t k = *(uint32_t*)data; k *= m;
k ^= k >> r;
k *= m; h *= m;
h ^= k; data += ;
len -= ;
} /* Handle the last few bytes of the input array */
switch(len) {
case : h ^= data[] << ;
case : h ^= data[] << ;
case : h ^= data[]; h *= m;
}; /* Do a few final mixes of the hash to ensure the last few
* bytes are well-incorporated. */
h ^= h >> ;
h *= m;
h ^= h >> ; return (unsigned int)h;
}
而redis则借助djb函数实现了不区分大小写的散列函数dict.c/dictGenCaseHashFunction:
unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
unsigned int hash = (unsigned int)dict_hash_function_seed; while (len--)
hash = ((hash << ) + hash) + (tolower(*buf++)); /* hash * 33 + c */
return hash;
}
以上三个散列函数(dictIntHashFunction, dictIntHashFunction, dictGenCaseHashFunction)分别用在了redis的不同地方,用以实现了不同场合下的散列需求,接下来的文章将会详细介绍。
REDIS源码中一些值得学习的技术细节02的更多相关文章
- REDIS源码中一些值得学习的技术细节01
redis.c/exitFromChild函数: void exitFromChild(int retcode) { #ifdef COVERAGE_TEST exit(retcode); #else ...
- redis源码学习之lua执行原理
聊聊redis执行lua原理 从一次面试场景说起 "看你简历上写的精通redis" "额,还可以啦" "那你说说redis执行lua脚本的原理&q ...
- 柔性数组(Redis源码学习)
柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...
- __sync_fetch_and_add函数(Redis源码学习)
__sync_fetch_and_add函数(Redis源码学习) 在学习redis-3.0源码中的sds文件时,看到里面有如下的C代码,之前从未接触过,所以为了全面学习redis源码,追根溯源,学习 ...
- 玩一把redis源码(一):为redis添加自己的列表类型
2019年第一篇文档,为2019年做个良好的开端,本文档通过step by step的方式向读者展示如何为redis添加一个数据类型,阅读本文档后读者对redis源码的执行逻辑会有比较清晰的认识,并且 ...
- Redis源码阅读(五)集群-故障迁移(上)
Redis源码阅读(五)集群-故障迁移(上) 故障迁移是集群非常重要的功能:直白的说就是在集群中部分节点失效时,能将失效节点负责的键值对迁移到其他节点上,从而保证整个集群系统在部分节点失效后没有丢失数 ...
- Redis源码阅读(三)集群-连接初始化
Redis源码阅读(三)集群-连接建立 对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供 ...
- 如何阅读 Redis 源码?ZZ
原文链接 在这篇文章中, 我将向大家介绍一种我认为比较合理的 Redis 源码阅读顺序, 希望可以给对 Redis 有兴趣并打算阅读 Redis 源码的朋友带来一点帮助. 第 1 步:阅读数据结构实现 ...
- Redis源码阅读---连接建立
对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供的集群功能是无中心的,命令请求可以发送到 ...
随机推荐
- swift 键盘属性与事件
1.键盘的类型 textField1.keyboardType = UIKeyboardType.default //系统默认的虚拟键盘 textField1.keyboardType = UIKey ...
- windowsxp设置开机不需密码,但是锁定后打开需要密码
方法一: 1.先设置好密码2.设置不输入密码自动登陆系统 在cmd下运行rundll32 netplwiz.dll,UsersRunDll,在打开的窗口中,取消“要使用本机,用户必须输入用户名和密码” ...
- 转换,2D,3D
一,转换定义: 1,能够改变元素的形状,尺寸,位置 2,转换分两种: 2D转换:只能在X,Y轴发生改变: 例子:旋转(rotate).拉伸(scale).平移(move).倾斜(skew) 3D转换: ...
- C# 生成表格代碼
public ActionResult btnExport(ReportViewModel model) { //接收需要导出的数据 L ...
- Runtime Reconfiguration
https://coreos.com/etcd/docs/latest/runtime-configuration.html Runtime Reconfiguration 运行时重新配置 etcd ...
- HDOJ(2056)&HDOJ(1086)
Rectangles HDOJ(2056) http://acm.hdu.edu.cn/showproblem.php?pid=2056 题目描述:给2条线段,分别构成2个矩形,求2个矩形相交面 ...
- [转帖]FPGA开发工具汇总
原帖:http://blog.chinaaet.com/yocan/p/5100017074 ----------------------------------------------------- ...
- vue-cli webpack 引入jquery
首先在package.json里的dependencies加入"jquery" : "^2.2.3",然后install 在webpack.base.conf. ...
- 转向Web
一直搞桌面软件开发,用C++绘界面那蛋疼的日子是记忆犹新,也不想钻研什么网络协议了,好好搞Web方面吧,它的开放很让人激动 Python是个好东西,适合许多场合,包括云计算,科学计算,软件测试,运维等 ...
- Html5知识
<!DOCTYPE> 声明 <!DOCTYPE>声明有助于浏览器中正确显示网页. 网络上有很多不同的文件,如果能够正确声明HTML的版本,浏览器就能正确显示网页内容. doct ...