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的更多相关文章

  1. REDIS源码中一些值得学习的技术细节01

    redis.c/exitFromChild函数: void exitFromChild(int retcode) { #ifdef COVERAGE_TEST exit(retcode); #else ...

  2. redis源码学习之lua执行原理

    聊聊redis执行lua原理 从一次面试场景说起   "看你简历上写的精通redis" "额,还可以啦" "那你说说redis执行lua脚本的原理&q ...

  3. 柔性数组(Redis源码学习)

    柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...

  4. __sync_fetch_and_add函数(Redis源码学习)

    __sync_fetch_and_add函数(Redis源码学习) 在学习redis-3.0源码中的sds文件时,看到里面有如下的C代码,之前从未接触过,所以为了全面学习redis源码,追根溯源,学习 ...

  5. 玩一把redis源码(一):为redis添加自己的列表类型

    2019年第一篇文档,为2019年做个良好的开端,本文档通过step by step的方式向读者展示如何为redis添加一个数据类型,阅读本文档后读者对redis源码的执行逻辑会有比较清晰的认识,并且 ...

  6. Redis源码阅读(五)集群-故障迁移(上)

    Redis源码阅读(五)集群-故障迁移(上) 故障迁移是集群非常重要的功能:直白的说就是在集群中部分节点失效时,能将失效节点负责的键值对迁移到其他节点上,从而保证整个集群系统在部分节点失效后没有丢失数 ...

  7. Redis源码阅读(三)集群-连接初始化

    Redis源码阅读(三)集群-连接建立 对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供 ...

  8. 如何阅读 Redis 源码?ZZ

    原文链接 在这篇文章中, 我将向大家介绍一种我认为比较合理的 Redis 源码阅读顺序, 希望可以给对 Redis 有兴趣并打算阅读 Redis 源码的朋友带来一点帮助. 第 1 步:阅读数据结构实现 ...

  9. Redis源码阅读---连接建立

    对于并发请求很高的生产环境,单个Redis满足不了性能要求,通常都会配置Redis集群来提高服务性能.3.0之后的Redis支持了集群模式. Redis官方提供的集群功能是无中心的,命令请求可以发送到 ...

随机推荐

  1. EntityFramwork入门

    原blog https://msdn.microsoft.com/zh-cn/data/ee712907 本人测试环境:VS2015+SQL Server 2008 R2 遇到问题 使用SQL Man ...

  2. J2EE应用监控后台执行SQL

    我们可能已经很熟悉在未使用数据库连接池的hibernate的环境下,配置p6spy和sql profiler.这在单独使用hibernate,以及项目初期是有效的.但是,在真实的开发环境下,往往是项目 ...

  3. Oracle重新装机后如何快速还原以前表和用户

    本人使用的oracle10g 首先拷贝以前的oradata 文件夹 一:重新创建oracle数据库后手动关闭oracle所有服务 二:将oradata中新创建的数据库目录改名,d:\app\user\ ...

  4. Mybatis 新增修改一条SQL

    如果在INSERT语句末尾指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE:如果不会导致唯一值 ...

  5. 让window.close不提示:您查看的网页正在试图关闭窗口。是否关闭此窗口?

    正常来说,当我们调用window.close来关闭从地址栏中打开的窗口时,IE会弹出提示说:您查看的网页正在试图关闭窗口,是否关闭此窗口? 你可以将window.close替换成下边的脚本,然后再测试 ...

  6. jq之ajax以及json数据传递

    <html> <head><meta http-equiv="Content-Type" content="text/html; chars ...

  7. nagios二次开发(一)---开发思想

    NAGIOS现状   从nagios的官网http://www.nagios.org/及其它已经公开的资料,我们可以知道:在web UI层nagios只提供了给我们查看图形界面的操作,界面上有简单的启 ...

  8. Arcgis Server发布服务

    提到Arcgis Server 服务的发布,做起来貌似很简单,就算电脑再卡,只要鼠标还能点,一个小时肯定能搞定,但是当你遇到问题的时候,就头大了,也许搞上个一两天都摸不着头脑,最后你采取的措施可能是一 ...

  9. Flash Builder常见菊紧问题集锦

    FB的错误多多,不定什么时候就让你蛋碎,路遇操蛋问题集锦如下: 1.有次用Flash Builder 4.7,打开之后马上自动关闭,试了几次都这样,解决办法如下: 到C:\Documents and ...

  10. Python+Google Geocoding

    本文主要介绍使用Python调用Google Geocoding API进行地址到地理坐标的转换. Google Geocoding参考https://developers.google.com/ma ...