Redis跳跃表

2015-03-01  本文已影响1227人  lintong

本文摘抄自redis 源码剖析

跳跃表是一种随机化的数据,跳跃表以有序的方式在层次化的链表中保存元素,效率和平衡树媲美 ——查找、删除、添加等操作都可以在对数期望时间下完成,并且比起平衡树来说,跳跃表的实现要简单直观得多。
以下是个典型的跳跃表例子:



从图中可以看到,跳跃表主要由以下部分构成:

跳跃表的实现

为了满足自身的功能需要,Redis对跳跃表进行了如下修改:

这个修改版的跳跃表由redis.h/zskiplist结构定义:

typedef struct zskiplist {
     // 头节点,尾节点 
    struct zskiplistNode *header, *tail;
   // 节点数量 
   unsigned long length;
   // 目前表内节点的最大层数 int level;
} zskiplist;

跳跃表的节点由redis.h/zskiplistNode定义:

typedef struct zskiplistNode { 
    //member 对象
    robj *obj;
   // 分值
   double score;
  // 后退指针
    struct zskiplistNode *backward;
  // 层 
  struct zskiplistLevel {
   // 前进指针
   struct zskiplistNode *forward;
  // 这个层跨越的节点数量
   unsigned int span; 
  } level[];
} zskiplistNode;

跳跃表的应用

和字典、链表或者字符串这几种在 Redis 中大量使用的数据结构不同,跳跃表在 Redis 的唯一作用,就是实现有序集数据类型

跳跃表将指向有序集的score值和member
域的指针作为元素,并以score 值为索引,对有序集元素进行排序。
举个例子,以下代码创建了一个带有 3 个元素的有序集:

redis> ZADD s 6 x 10 y 15 z
(integer) 3
redis> ZRANGE s 0 -1 WITHSCORES
1) "x"
2) "6"
3) "y"
4) "10"
5) "z"
6) "15"

在底层实现中,Redis 为x、y和z三个member分别创建了三个字符串,值分别为double类型的6、10和15,然后用跳跃表将这些指针有序地保存起来,形成这样一个跳跃表:



为了方便展示,在图片中我们直接将member和score值包含在表节点中,但是在实际的定义中,因为跳跃表要和另一个实现有序集的结构(字典)分享member和score值,所以跳跃表只保存指向member
和score的指针。

上一篇 下一篇

猜你喜欢

热点阅读