我想了一下:按照前文所讲的内容,应该是4 。但是,假如是4,存在和收缩后的长度相等,是不是又该扩容?
假如收缩后 长度为4
,不仅不会收缩,甚至还会
报错
;
我们回过头来再看看设定:题目可能成立吗?哈希表的扩容都是 2倍增长的,最小是4,4 ===》 8 ====》 16 =====》 32 ======》 64 ====》 128
“
也就是说:不存在长度为 40多的情况,只能是64 。但是如果是64的话,64 X 0.1(收缩界限)= 6.4,也就是说在减少到6的时候,哈希表就会收缩,会缩小到多少呢?是8 。此时,再继续减少到4,也不会再收缩了 。所以,根本不存在一个长度大于40,但是存在的元素为4的哈希表的 。
”
扩容步骤
文章插图
收缩步骤
文章插图
渐进式refresh在"扩容步骤"和"收缩步骤" 两幅动图中每幅图的 第四步骤 “将ht[0]中的数据利用哈希函数 重新计算,rehash到ht[1]”,并不是一步完成的,而是分成N多步,循序渐进地完成的 。因为hash中有可能存放几千万甚至上亿个key,毕竟Redis中每个 hash中可以存 2^32-1 键值对 (40多亿),假如一次性将这些键值rehash的话,可能会导致服务器在一段时间内停止服务,毕竟哈希函数就得 计算一阵子呢 (对吧(#^.^#)) 。
哈希表的refresh是分多次、渐进式进行的 。渐进式refresh和下图中左边橘黄色的“统筹”部分中的rehashidx密切相关:
- rehashidx 的数值就是现在rehash的 元素位置
- rehashidx 等于-1的时候说明没有在进行refresh
以扩容步骤 举例 :
文章插图
intset整数集合是 集合键 的底层实现方式之一 。
文章插图
跳表跳表这种数据结构长这样:
文章插图
redis中把跳表抽象成如下所示:
文章插图
看这个图,左边“统筹”,右边实现 。
统筹部分 有几点要说:
- header: 跳表表头
- tail:跳表表尾
- level:层数最大的那个节点的层数
- length:跳表的长度
- 表头:是链表的哨兵节点,不记录主体数据 。是个 双向链表分值 是有顺序的
- o1、o2、o3是节点所保存的成员,是一个指针,可以指向一个SDS值 。
- 层级高度最高是32 。没每次创建一个新的节点的时候,程序都会 随机生成 一个介于1和32之间的值作为level 数组的大小,这个大小就是“高度”
就像这样:
文章插图
字符串
文章插图
其中:embstr和raw都是由 SDS动态字符串 构成的 。唯一区别是: raw 是分配内存的时候,redis object和sds各分配一块内存,而embstr是redisobject和raw 在一块儿内存 中 。
列表
文章插图
列表
hash
文章插图
哈希
set
文章插图
set
set
文章插图
zset
跳跃表是一种 有序 数据结构,它通过在 每个节点 中维持 多个指向其它节点 的指针,从而达到快速访问节点的目的 。具有如下 性质 :
1、由很多层结构组成;
推荐阅读
- 李自成灭亡的真正原因,李自成失败的根本原因是什么
- 朱元璋杀李善长的真正原因是什么?,朱元璋为何杀李善长全家
- OceanBase开源,11张图带你了解分布式数据库的核心知识
- reflector 带你彻底搞懂MyBatis的底层实现之反射工具箱
- 真正降血压的茶,降血压喝什么茶最好
- 一篇文章带你搞懂Python中的类
- 软件测试知识点3大场景带你了解单元测试
- 秦始皇不立皇后的真正原因,秦始皇为什么终身不立后
- 历史上真正的刘彧,刘彧是不是昏君
- 乾隆身世之谜-到底谁是弘历生母-乾隆果真是汉女所生-?乾隆与其母的真正关系_1