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官方提供的集群功能是无中心的,命令请求可以发送到 ...
随机推荐
- dijit.form.Select 基本用法
dijit.form.Select 1)创建: var division = new dijit.form.Select({ id: "Division",//id必须唯一 nam ...
- Java基础--定时任务Timer
Java基础--定时任务Timer 一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.Time ...
- js 中数字问题
在js中请注意数字是没有长度的, 不能使用for循环遍历数字的长度 操作时通过.toString()把数字转换成字符串后通过字符串的.length 属性得到长度
- Datatable 列查询,统计值
Column 列查询,如下: var dt = CommonUtil.ToDataTable(dataJson); //判断是否有当前日期数据 var systemDateTime = new Com ...
- Linux资源监控(Nmon)
1.下载nmon_linux_14g.tar.gz 2.解压nmon_linux_14g.tar.gz #tar -zxvf nmon_linux_14g.tar.gz 3. 为nmon_x86_64 ...
- {MBR}{Grub}win7+Linux恢复MBR
准备:win7安装盘,Linux安装盘 Step1:在linux下查看一下硬盘的信息fdisk -l,找到hd0和ext分区的信息 Step2: 重启插入win7安装盘,对windows系统恢复Gru ...
- 【工作笔记】BAT批处理学习笔记与示例
BAT批处理学习笔记 一.批注里定义:批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件,其扩展名为BAT或者CMD,这些命令统称批处理命令. 二.常见的批处理指令: 命令清单: 1.RE ...
- SQL优化 CREATE STATISTICS
CREATE STATISTICS 语法: https://msdn.microsoft.com/zh-cn/library/ms188038.aspx STATISTICS优化中的使用案例: htt ...
- window.print() 去掉页眉页脚及打印链接【转载】
页面中添加样式: <style media="print"> @page { size: auto; /* auto is the initial value */ m ...
- CentOS6.3连接Xshell出现的问题(连接失败--需要设置ONBOOT=“yes”,开启网卡驱动)
小白记录: 安装Xshell之后连接CentOS6.3的baseService版本,连接不上, service network restart 只有两个OK, 百度查找资料后--得到结论:网卡设置之 ...