模板基于eyoucms内核制作,模板编码为UTF8 ,适合行业:机械设备类企业。

文件:n459.com/file/25127180-477758809

以下内容无关:

-------------------------------------------分割线---------------------------------------------

Redis 中,字典是基础结构。Redis 数据库数据、过期时间、哈希类型都是把字典作为底层结构。

字典的结构
哈希表
哈希表的实现代码在:dict.h/dictht,Redis 的字典用哈希表的方式实现。

typedef struct dictht {
// 哈希表数组,俗称的哈希桶(bucket)
dictEntry **table;
// 哈希表的长度
unsigned long size;
// 哈希表的长度掩码,用来计算索引值,保证不越界。总是 size - 1
// h = dictHashKey(ht, he->key) & n.sizemask;
unsigned long sizemask;
// 哈希表已经使用的节点数
unsigned long used;
} dictht;
table 是一个哈希表数组,每个节点的实现在 dict.h/dictEntry,每个 dictEntry 保存一个键值对。
size 属性记录了向系统申请的哈希表的长度,不一定都用完,有预留空间的。
sizemask 属性主要是用来计算 索引值 = 哈希值 & sizemask,这个索引值决定了键值对放在 table 的哪个位置。它的值总是 size - 1,其实我有点不明白为啥计算的时候不直接用 size - 1,知道的大佬请明示。
used 属性用来记录已经使用的节点数,size - use 就是未使用的节点啦。
下图展示了一个大小为 4 的空哈希表结构,没有任何键值对
一个空哈希表

哈希节点
哈希表 dictht 的 table 的元素由哈希节点 dictEntry 组成,每一个 dictEntry 就是一个键值对

typedef struct dictEntry {
// 键
void *key;
// 值
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
// 下一个哈希节点,用于哈希冲突时拉链表用的
struct dictEntry *next;
} dictEntry;
next 指针是用于当哈希冲突的时候,可以形成链表用的。后续会将

字典
Redis 的字典实现在: dict.h/dict 。

typedef struct dict {
// 哈希算法
dictType *type;
// 私有数据,用于不同类型的哈希算法的参数
void privdata;
// 两个哈希表,用两个的原因是 rehash 扩容缩容用的
dictht ht[2];
// rehash 进行到的索引值,当没有在 rehash 的时候,为 -1
long rehashidx; /
rehashing not in progress if rehashidx == -1 /
// 正在跑的迭代器
unsigned long iterators; /
number of iterators currently running */
} dict;

// dictType 实际上就是哈希算法,不知道为啥名字叫 dictType
typedef struct dictType {
// hash方法,根据 key 计算哈希值
uint64_t (*hashFunction)(const void *key);
// 复制 key
void *(*keyDup)(void *privdata, const void *key);
// 复制 value
void *(*valDup)(void *privdata, const void *obj);
// key 比较
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
// 销毁 key
void (*keyDestructor)(void *privdata, void *key);
// 销毁 value
void (*valDestructor)(void *privdata, void *obj);
} dictType;
dictType 属性表示字典类型,实际上这个字典类型就是一组操作键值对算法,里面规定了很多函数。
privdata 则是为不同类型的 dictType 提供的可选参数。
如果有需要,在创建字典的时候,可以传入dictType 和 privdata。

dict.c

// 创建字典,这里有 type 和 privdata 可以传
dict *dictCreate(dictType *type, void *privDataPtr) {
dict *d = zmalloc(sizeof(*d));
_dictInit(d,type,privDataPtr);
return d;
}

// 初始化字典
int _dictInit(dict *d, dictType *type, void *privDataPtr) {
_dictReset(&d->ht[0]);
_dictReset(&d->ht[1]);
d->type = type;
d->privdata = privDataPtr;
d->rehashidx = -1;
d->iterators = 0;
return DICT_OK;
}
下图是比较完整的普通状态下的 dict 的结构(没有进行 rehash,也没有迭代器的状态):
dict 结构图# 哈希算法
当字典中需要添加新的键值对时,需要先对键进行哈希,算出哈希值,然后在根据字典的长度,算出索引值。

// 使用哈希字典里面的哈希算法,算出哈希值
hash = dict->type->hashFunction(key)
// 使用 sizemask 和 哈希值算出索引值
idx = hash & d->ht[table].sizemask;
// 通过索引值,定位哈希节点
he = d->ht[table].table[idx];
哈希冲突
哈希冲突指的是多个不同的 key,算出的索引值一样。

Redis 解决哈希冲突的方法是:拉链法。就是每个哈希节点后面有个 next 指针,当发现计算出的索引值对应的位置有其他节点,那么直接加在前面节点后即可,这样就形成了一个链表。

下图展示了 {k1, v1} 和 {k2, v2} 哈希冲突的结构。
假设 k1 和 k2 算出的索引值都是 3,当 k2 发现 table[3] 已经有 dictEntry{k1,v1},那就 dictEntry{k1,v1}.next = dictEntry{k2,v2}。
哈希冲突拉链表的示意图

rehash
随着操作的不断进行,哈希表的长度会不断增减。哈希表的长度太长会造成空间浪费,太短哈希冲突明显导致性能下降,哈希表需要通过扩容或缩容,让哈希表的长度保持在一个合理的范围内。
Redis 通过 ht[0] 和 ht[1] 来完成 rehash 的操作,步骤如下:

为 ht[1] 分配空间,分配的空间长度有两种情况:
扩容:第一个大于等于 ht[0].used * 2 的 2n 的数,例如 ht[0].used = 3,那么分配的是距离 6 最近的 23=8
缩容:第一个大于等于 ht[0].used / 2 的 2n 的数,例如 ht[0].used = 6,那么分配的是距离 3 最近的 22=4
将 h[0] 上的键值对都迁移到 h[1],迁移的时候都是重新计算索引值的。由于 h[1] 的长度较长,之前在 h[0] 拉链的元素大概率会被分到不同的位置。
ht[0] 所有的键值对迁移完之后,h[0] 释放,然后 h[0] = h[1],并把 h[1] 清空,为下次 rehash 准备
渐进式 rehash
上面说的 rehash 中的第二步,迁移的过程不是一次完成的。如果哈希表的长度比较小,一次完成很快。但是如果哈希表很长,例如百万千万,那这个迁移的过程就没有那么快了,会造成命令阻塞!
下面来说说,redis 是如何渐进式地将 h[0] 中的键值对迁移到 h[1] 中的:

为 h[1] 开辟空间,字典同时持有 h[0] 和 h[1]
字典中的 rehashidx 维护了 rehash 的进度,设置为 0 的时候,开始 rehash
字典每次增删改查的时候,除了完成指定操作之外,还会顺带把 rehashidx 上的整条链表迁移到 h[1] 中。迁移完之后 rehashidx + 1
随着字典的不断读取、操作,最终 h[0] 上的所有键值对都会迁移到 h[1] 中。全部迁移完成之后 rehashidx = -1
这种渐进式 rehash 的方式的好处在于,将庞大的迁移工作,分摊到每次的增删改查中,避免了一次性操作带来的性能的巨大损耗。
缺点就是迁移过程中 h[0] 和 h[1] 同时存在的时间比较长,空间利用率较低。

下面一系列的图,演示了字典是如何渐进式地 rehash ( 图片来自 《Redis 设计与实现》图片集 )

易优cms响应式离心风机机械制造公司网站模板源码 自适应手机端相关推荐

  1. 易优cms响应式少儿舞蹈培训机构网站模板源码 自适应手机端

    介绍 模板基于eyoucms内核制作,模板编码为UTF8 ,适合行业:学校培训类企业. 下载链接 http://www.bytepan.com/IUv80QJy7C4 图片

  2. 易优cms红色风格春节年货礼品公司网站模板源码

    介绍: 易优cms红色风格春节年货礼品公司网站模板源码,喜欢的可以拿走! 网盘下载地址: http://kekewangLuo.net/egbhbc4kDfY0 图片:

  3. 易优cms响应式文具用品益智玩具公司网站模板源码 自适应手机端

    介绍 模板基于eyoucms内核制作,模板编码为UTF8 ,适合行业:文具玩具类企业. 下载链接 http://www.bytepan.com/KBhBhGUXsZB 图片

  4. 易优cms响应式网站模板,EyouCMS网络科技公司网站模板

    易优EyouCMS模板,响应式互联网类企业网站模板,适用于科技公司.网络公司,模板自带eyoucms内核,无需再下载eyou系统,原创设计.手工书写DIV+CSS,完美兼容IE7+.Firefox.C ...

  5. 易优CMS响应式网站建设网络科技网站模板源码下载

    这个模板小子看了下,确实挺好看的,正儿八经可以做个人或者工作室的企业官网,特效也不错,排版也很工整,eyoucms的挺好的.模板自带eyoucms内核,无需再下载eyou系统 原创设计.手工书写DIV ...

  6. 易优cms海报画册印刷设计公司网站模板源码 带手机端

    易优cms海报画册印刷设计公司网站模板源码 带手机端 带后台 模板基于eyoucms内核制作,模板编码为UTF8 ,适合行业:广告设计类企业. 文件:n459.com/file/25127180-47 ...

  7. 苹果cmsV10响应式大橙子和B站模板源码(带安装教程)

    简介: 苹果cmsV10响应式大橙子和B站模板源码(带安装教程) 网盘下载地址: http://kekewangLuo.cc/hd8U4K3gpSs0 图片:

  8. 易优cms企业建站系统v1.5.1 含小程序源码

    介绍: 易优cms企业建站系统是由php+mysql开发的一套专门用于中小企业网站建设的开源cms. 可以用来快速建设一个企业网站( PC,手机,微信都可以访问).后台操作简单,维护方便. 功能特色: ...

  9. [响应式外贸灯具机械英文网站模板] 织梦模板+机械电子汽车外贸网站+自适应手机

    介绍 响应式外贸灯具机械电子英文网站dede源码织梦模板(自适应手机) 纯英文dede源码织梦模板,适合做机械电子,灯具,汽车等外贸公司网站来使用. 下载链接 http://www.bytepan.c ...

最新文章

  1. Win2D 官方文章系列翻译 - 避免内存泄漏
  2. WP老杨解迷:可知评论系统还能勾搭用户呢
  3. 2009暑期实践报告
  4. Android Studio 插件开发详解四:填坑
  5. java进程优先级,跨平台方式改变java进程优先级
  6. 配置SQL Server 2012 AlwaysOn ——step1 建立AD域及DNS配置
  7. (42)css特异性
  8. SCPPO(十):网站发布中的问题锦集—手动发布网站
  9. PostGis路径分析
  10. 超级搜索术3-吸收应用/一键直达
  11. 互动投影游戏加密狗复制教程!
  12. 计算机英语pre,如何区别英语前缀pri,pro,per,pre?
  13. postman设置为中文
  14. ie ajax十分卡,解决JQuery .ajax 在IE下卡死问题
  15. SOA、网格计算、云计算与P2P技术
  16. Day2-Python基础2---列表、元组操作
  17. ImportError: cannot import name ‘get_all_providers‘ from ‘onnxruntime.capi._pybind_state‘
  18. 企查查访问超频怎么办_Springboot与Selenium合体变蜘蛛爬企查查
  19. d3.js画金庸小说力导向图
  20. 谷歌G1反抗iPhone

热门文章

  1. TensorFlow学习笔记——车牌标志识别分类
  2. 中专生边旅游边办网站年赚30万
  3. android 兼容包(可兼容低版本系统)
  4. wandb: Network error (ConnectionError), entering retry loop.
  5. 新升级手机端erp进销存源码ERP多仓库管理系统源码
  6. HTML实现右下角闪烁弹窗
  7. Execution failed for task ':app:mergeDebugResources'
  8. 关于路面裂缝数据集crack500的设置
  9. 软文推广写作掌握多种文笔风格让文字“如沐春风”
  10. 【图像分割】医学图像均值聚类+OUST+区域生长法图像分割【含GUI Matlab源码 2210期】