Redis 学习笔记_数据结构(2)

跳跃表(skiplist)
跳跃表的实现
typedef struct zskiplist{
    //表头表尾节点
    struct skiplistNode *header,*tail;
    
    //表中节点数量
    unsigned long length;
    
    //表中最大的节点层数
    int level;
    
} zskiplist;

typedef struct zskiplistNode{
    struct zskiplistLevel{
        //前进指针
        struct zskiplistNode *forward;
        
        //跨度
        unsigned int span;
        
    } level[];
    
    //后退指针
    struct zskiplistNode *backward;
    
    //分值
    double score;
    
    //成员对象
    obj *obj;
    
} zskiplistNode;

展示图:在这里插入图片描述

总结
    1.跳跃表是有序集合的底层实现之一。
    2.Rcdis的 跳 跃 表 实 现 由zskiplist和zskiplistNode两 个 结 构 组 成 , 其 中zskiplist用P保 存 跳 跃 表 信 息 ( 比 如 表 头 节 点 、 表 尾 节 点 、 长 度  而zskiplistNode则 用P表 示跳跃表节点。
    3.每个跳跃表节点的层卨都是1至32之间的随机数。
    4.在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是 唯一的。
    5.跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。
整数集合

集合键的底层实现之一,当一个集合只包含整数值元素时,并且整个集合的元素数量不多时,就会使用该数据结构作为集合键的底层实现。

整数集合的实现
typedef struct intset{
    //编码方式
    uint32_t encoding;
    
    //集合包含的元素数量
    uint32_t length;
    
    //保存元素的数组
    int8_t contents[];
    
} intset;

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

encoding

encoding最小值,最大值
INTSET_ ENC_ INT16-32768,32767 (-215~215-1)
INTSET_ ENC_ INT32-2147483648,2147483647 (-231~231-1)
INTSET_ ENC_ INT64(-263~263-1)
升级(upgrade) (不支持降级)

每当我们要将一个新元素添加到整数集合里面,并且新元素的类型比整数集合现有所有元素的类型都要长时,整数集合需要先进行升级( upgrade),然后才能将新元素添加到整数集合里面。

三个步骤:

  • 根据新元素的类型,扩展整数集合底层数组的空间大小,并为新元素分配空间。
  • 将底层数组现有的所有元素都转换成与新元素相同的类型,并将类型转换后的元素放置到正确的位上,而且在放置元素的过程中,需要继续维持底层数组的有序性质不变。
  • 将新元素添加到底层数组里面

引发升级的新元素摆放位置:当大于所有元素,放在最末尾(length-1); 小于所有元素,则放在最开头(0)

好处:

  • 提升灵活性:因为整数集合可以通过自动升级底层数组来适应新元素,所以我们可以随意地将int16_ t、int32 _ t或者int64_ t 类型的整数添加到集合中,而不必担心出现类型错误,这种做法非常灵活。
  • 节约内存
总结
  • 整数集合是集合键的底层实现之一。

  • 整数集合的底层实现为数组,这个数组以有序、无重复的方式保存集合元素,在有
    需要时,程序会根据新添加元素的类型,改变这个数组的类型。

  • 升级操作为整数集合带来了操作上的灵活性,并且尽可能地节约了内存。

  • 整数集合只支持升级操作,不支持降级操作。

压缩列表

压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做列表键的底层实现。
展示图:
在这里插入图片描述

属性类型长度用途
zlbytesuint32_ t4字节记录整个压缩列表占用的内存字节数:在对压缩列表进行内存重分配,或者计算zlend的位置时使用
zltailuint32_ t4字节记录压缩列表表尾节点距离压缩列表的起始地址有多少字节:通过这个偏移量,程序无须遍历整个压缩列表就可以确定表尾节点的地址
zllenuint16_ t2字节记录了压缩列表包含的节点数量:当这个属性的值小于( 65535)时,这个属性的值就是压缩列表包含节点的数量;当这个值等于UINT16_ MAX时,节点的真实数量需要遍历整个压缩列表才能计算得出
entryX列表节点不定压缩列表包含的各个节点,节点的长度由节点保存的内容决定
zlenduint8_ t1字节特殊值0xFF (十进制255),用于标记压缩列表的末端
总结
  • 压缩列表是一种为节约内存而开发的顺序型数据结构。
  • 压缩列表被用作列表键和哈希键的底层实现之一。
  • 压缩列表可以包含多个节点,每个节点可以保存一一个字节数组或者整数值。
  • 添加新节点到压缩列表,或者从压缩列表中删除节点,可能会引发连锁更新操作,但这种操作出现的几率并不高。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值