redis-SortSet底层结构

目录

ziplist 

跳跃表(skiplist)新增

第一次抛硬币为正 

第二次抛硬币

为反面

 为正面

 为什么使用抛硬币的方式

跳跃表删除

跳跃表&B+树


sortedset同时会由两种数据结构支持,ziplistskiplist.

只有同时满足如下条件是,使用的是ziplist,其他时候则是使用skiplist

  • 有序集合保存的元素数量小于128个
  • 有序集合保存的所有元素的长度小于64字节

ziplist 

ziplist作为存储结构时候,每个集合元素使用两个紧挨在一起的压缩列表结点来保存,

第一个节点保存元素的成员,第二个元素保存元素的分值.

ziplist 是一个特殊的双向链表
特殊之处在于:没有维护双向指针:prev next;而是存储上一个 entry的长度和 当前entry的长度,通过长度推算下一个元素在什么地方。
牺牲读取的性能,获得高效的空间存储,因为(简短字符串的情况)存储指针比存储entry长度 更费内存。这是典型的“空间换时间”。

ziplist的主要优点是节省内存,但它查找操作只能按顺序查找(可以是从前往后、也可以从后往前)。
ziplist将数据按照一定规则编码在一块连续的内存区域,目的是节省内存,这种结构并不擅长做修改操作。一旦数据发生改动,就会引发内存realloc,可能导致内存拷贝。

ziplist使用局限性
字段、值比较小,才会用ziplist。

当使用skiplist作为存储结构时,使用skiplist按序保存元素分值,使用dict来保存元素和分值的对应关系

redisDb 整体使用 dict字典 来存储键值对KV;
字典中的每一项,使用dictEntry ,代表KV键值;类似于HashMap中的键值对Entry。

跳跃表(skiplist)新增

  1. 新节点和各层索引节点逐一比较,确定原链表的插入位置。O(logN)
  2. 把索引插入到原链表。O(1)
  3. 利用抛硬币的随机方式,决定新节点是否提升为上一级索引。结果为“正”则提升并继续抛硬币,结果为“负”则停止。O(logN)

第一次抛硬币为正 

硬币结果为正,插入的节点提拔为上一层索引

 提拔为索引节点的数据,继续抛硬币,结果为正,则把该索引节点继续提升为上层节点

第二次抛硬币

为反面

 为正面

 为什么使用抛硬币的方式

1. 跳跃表删除和添加节点是不可预测的,很难用一种有效的算法来保证跳跃表的索引始终均匀

2. 随机抛硬币的方式虽然不能保证索引均匀分布,却可以让大体的数据结构趋于均匀

跳跃表删除

  1. 自上而下,查找第一次出现节点的索引,并逐层找到每一层对应的节点。O(logN)
     
  2. 删除每一层查找到的节点,如果该层只剩下1个节点,删除整个一层(原链表除外)。O(logN)

跳跃表&B+树优劣

跳跃表的优点:

维持结构平衡的成本比较低,完全依靠随机

B+树

在多次插入删除后,需要rebalance来重新调整结构平衡

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值