Redis Skip List(跳跃表)

跳跃表

跳跃表(Skip List)是一种用于有序元素序列快速搜索的数据结构。它的效率和红黑树以及AVL(自平衡二叉查找树)相近,但是实现起来更加容易(相对于复杂的自平衡算法)。

 

大概结构如下:

在最原始的已排序的链表基础上通过添加多个层级,理想情况下每个层级节点数是上一个层级1/2,查找时通过最上层开始,利用需要查找的值与当前层级值对比缩小范围并通过下一层进一步缩小范围,最终找到查询值的方式(类似于二分查找方式)。

 

Redis的跳跃表

Redis使用跳跃表作为有序集合的底层实现之一,如果一个有序集合包含的元素比较多或者集合中的元素时比较长的字符串时,Redis会使用跳跃表作为有序集合键的底层实现。

Redis跳跃表大致结构如下:

分为zskiplistNode和zskiplist两个结构,代码如下:

redis.h/zskiplistNode:

typedef struct zskiplistNode {

  // 成员对象
  robj *obj;

  // 分值
  double score;

  // 后退指针
  struct zskiplistNode *backward;

  // 层
  struct zskiplistLevel {

    // 前进指针
    struct zskiplistNode *forward;

    // 跨度
    unsigned int span;

  } level[];

} zskiplistNode;

level数组包含了当前元素在不用层高的下一个元素指针和跨度,Redis中程序会根据幂次定律(power law, 越大的数出现的概率越小)随机生成一个介于1~32之间的值作为level数组的大小,这个大小就是层的“高度”。

span表示跨度,由于底层的链表是有序的,所以从头部到当前节点跨度之和也就是元素的排位。用于Redis有序集合的ZRANK命令获取元素排行。

backward回退指针用于逆序遍历链表,对应Redis有序集合的ZREVRANGE命令。

 

redis.h/zskiplist:

typedef struct zskiplist {

  // 表头节点和表尾节点
  struct zskiplistNode *header, *tail;

  // 表中节点的数量
  unsigned long length;

  // 表中层数最大的节点的层数
  int level;

} zskiplist;

 

转载于:https://my.oschina.net/u/1413049/blog/1514103

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值