第七课——简单动态字符串、链表、字典、压缩列表
第七课时作业
静哥
by 2016.4.5~2016.4.10
【作业描述】
1.解释redis数据库是怎么扩容的?
2.用几句话描述sds结构和压缩列表
【作业-1:解释redis数据库是怎么扩容的】
Redis数据库是使用字典作为底层实现的,对数据库的增删改查操作也是构建在对字典的操作之上。因此,redis数据库的扩容本质上就是字典的扩容。
Redis数据库是使用字典作为底层实现的;而字典使用哈希表作为底层实现;哈希表则可以由多个哈希表节点构成;哈希表节点里保存字典中的一个键值对。
- 对哈希表节点、哈希表、字典结构的学习和理解
- 哈希表节点(dictEntry)
哈希表节点使用dictEntry结构表示,每个dictEntry结构都保存着一个键值对;
- key属性:保存键值对中的键;key的数据类型是void *,也就是空类型指针,即任何类型的指针;
- v属性:是一个共用体结构(各变量“互斥“),存放键值对的值,这个值可以是一个指针,也可以是uint64_t整数,也可以是int_64_t整数
- next属性:指向另一个哈希表节点的指针,该指针可以将多个哈希值相同的键值对连接在一起,来解决键冲突的问题,如下例子:
- 哈希表(dictht)
- table属性:数据类型是dictEntry **,也就是dictEntry类型的数组,数组中每个元素都是指向dictEntry哈希表节点的指针;
- size属性:记录hash表的大小;也就是dictEntry[num]数组的长度
- used属性:记录哈希表目前已经有的节点,也就是键值对(dictEntry结构)的个数;
- Sizemask属性:值是size-1,这个属性和哈希值一起决定一个键应该被放到table数组(dictEntry[num]数组)的哪个索引上面;
3、字典(dict)
Type属性和privdata属性是针对不同类型的键值对,为创建多态字典而设置的;
- type属性:一个指向dictType结构的指针,每个dictType结构保存一簇用于操作特点类型键值对的函数,redis会为用途不同的字典设置不同的类型特点函数;
- privdata属性:保存了需要传给哪些类型特定函数的可选参数;
- ht属性:包含2项的数组,ht[0]和ht[1],这两个元素都是一个dictht哈希表,一般情况下,字典只使用ht[0],ht[1]哈希表只会在对ht[0]哈希表进行rehash时使用。
- rehashidx属性:记录了rehash目前的进度,如果没有在进行rehash,则rehashidx=-1,在进行rehash,则rehashidx=0;
- 以下是一个完整的字典,没有进行rehash的字典:
二、对哈希算法的学习和理解
1、redis程序根据键值对的键,计算出哈希值和索引值,然后根据索引值将包含键值对的哈希表节点放到哈希表数组的指定索引上;
以下是,redis计算哈希值和索引值的方法:
- 多个哈希表节点都有一个next指针,构成一个单向链表,被分配到同一个索引的多个节点可以用单向链表连接起来,解决链冲突问题;
- 当哈希表保存的键值对数量太多或者太少时,程序需要对哈希表的大小进行相应的扩展或者收缩;扩展和收缩哈希表的工作可以通过执行rehash(重新散列)操作来完成;
【作业-2:用几句话描述sds结构和压缩列表】
- sds结构
- C语言里自带的字符串是以空格符结尾的字符数组;
- Redis里没有直接使用C语言的字符串,而是自己构建了名为SDS的抽象类型
- 压缩列表
- 压缩列表是redis为了节约内存而开发的,由一系列特殊编码的连续内存块构成的顺序型(sequence)数据结构;一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值;