redis数据结构和对象二

跳跃表(skiplist)
跳跃表是一种有序数据结构。跳跃表支持平均O(logN),最坏O(N)复杂度的节点查找,大部分情况下,跳跃表的效率可以和平衡树相媲美,并且因为跳跃表的实现比平衡树简单,所有不少程序都用跳跃表代替平衡树。Redis使用跳跃表作为有序集合的底层实现,另一个是在集群节点中用作内部数据结构

1.1 跳跃表的实现

redis数据结构和对象二

typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist;

header:指向跳跃表的表头节点。

tail:指向跳跃表的表尾节点。

level:记录目前跳跃表内,层数最大的那个节点的层数(表头节点的层数不计算在内)

lenght:记录跳跃表的长度,即跳跃表目前包含节点的数量(表头节点的层数不计算在内)

typedef struct zskiplistNode {
robj *obj;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
} level[];
} zskiplistNode;

层(level):节点中用L1, L2, L3等字样标记节点的各个层,L1代表第一层,L2代表第二层,依次类推。每个层都带有两个属性:前进指针和跨度。

前进(level[i].forward)属性:用于从表头向表尾方向的访问节点。遍历跳跃表中所有节点的路径。

跨度(level[i].span)属性:用于记录两个节点之间的距离。两个节点直接的跨度越大,他们相距的就越远。指向NULL的所有指针的跨度都为0,因为他们没有连向任何节点。

后退(backward)指针:节点中用BW字样标记节点的后退指针,他指向位于当前节点的前一个节点。后退指针在程序从表尾向表头遍历使用。

分值(score):各个节点中的1.0,2.0和3.0是节点所保存的分值。在跳跃表中节点按各自所保存的分值从小到大排列。

成员对象(obj): 各个节点中o1、o2、o3是节点所保存的成员对象

整数集合(intset)

整数集合(intset)是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合元素数量不多时,Redis就会使用整数集合作为集合键的底层实现。

typedef struct intset {
uint32_t encoding;
uint32_t length;
int8_t contents[];
} intset;

contents数组时整数集合的底层实现:各个元素在数组中按值大小从小到大有序地排列,并且数组中不包含任何重复项。

length属性记录了整数集合包含的元素数量,即contents数组数组的长度。
虽然intset结构将contents属性声明为int8_t类型的数组,但实际上contents数组并不保存任何int8_t类型的值,contents数组的真正类型取决于encoding属性值。

如果encoding属性的值为INTSET_ENC_INT16,那么contents就是一个int16_t类型的数组。数组长度sizeof(int16_t)*length

如果encoding属性的值为INTSET_ENC_INT32,那么contents就是一个int32_t类型的数组。数组长度sizeof(int32_t)*length

如果encoding属性的值为INTSET_ENC_INT64,那么contents就是一个int64_t类型的数组。数组长度sizeof(int64_t)*length

redis数据结构和对象二

整数集合升级,不支持降级。
每当将一个元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先进行升级,然后才能添加到整数集合里面。升级分三步进行:
1)根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。
2)将底层数组现有的所有元素都转换成与新元素相同的元素类型,并将类型转换后的元素放置到正确的位置。
3)将新元素添加到底层数组里面。
升级的好处
1)提升灵活性。因为语言时静态类型语言,不能将两种不同类型的值放在同一个数据结构里面。因为整数集合可以自动升级底层数组来适应新元素。
2)节约内存。 要让一个数组同时可以保存int16_t,int32_t, int64_t三种类型通常做法直接使用int64_t类型作为数组,这样出现浪费内存。

升级例子:将一个类型int32_t的数值65535添加到int16_t类型集合里面:

redis数据结构和对象二


redis数据结构和对象二


redis数据结构和对象二

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssppw.html