Redis数据结构:跳表

Redis数据结构:跳表

引言

Redis的有序集合有两种实现方式:

  1. 基于压缩列表(ziplist)实现(当数据量较少时,采用此种方式)
  2. 基于跳跃表(skiplist)和字典实现

所以,跳表是Redis中实现有序结合采用数据结构之一。关于跳跃表这种数据结构更详细的介绍,可以关注本博客的另一篇文章数据结构之跳跃表。本文重点讲解跳跃表在Redis上的具体实现。

在此之前,我们要知道的Redis有序集合的一些特性:

  1. 每个元素包含两个部分,成员对象分值。集合按分值大小有序排列。
  2. 分值允许重复,但成员对象是唯一的。

实现

跳跃表节点结构定义

从代码我们可以看出,Redis采用的是双端链表,既有前进指针,也有后退指针。要注意的是,后退指针只有一个,所以从后往前遍历,不能”跳”着走,只能老老实实一步一步脚印。前进指针则相反。

  • obj: 表示成员对象;实际上是个字符串对象,保存着一个SDS值。
  • score:分值,double类型的浮点数

跳跃表结构定义

结构总览图

image-20190105042459067

跳跃表API

函数作用复杂度
zslCreateNode创建并返回一个新的跳跃表节点最坏 O(1)O(1)
zslFreeNode释放给定的跳跃表节点最坏 O(1)O(1)
zslCreate创建并初始化一个新的跳跃表最坏 O(1)O(1)
zslFree释放给定的跳跃表最坏 O(N)O(N)
zslInsert将一个包含给定 scoremember 的新节点添加到跳跃表中最坏 O(N)O(N) 平均 O(logN)O(log⁡N)
zslDeleteNode删除给定的跳跃表节点最坏 O(N)O(N)
zslDelete删除匹配给定 memberscore 的元素最坏 O(N)O(N) 平均 O(logN)O(log⁡N)
zslFirstInRange找到跳跃表中第一个符合给定范围的元素最坏 O(N)O(N) 平均 O(logN)O(log⁡N)
zslLastInRange找到跳跃表中最后一个符合给定范围的元素最坏 O(N)O(N) 平均 O(logN)O(log⁡N)
zslDeleteRangeByScore删除 score 值在给定范围内的所有节点最坏 O(N2)O(N2)
zslDeleteRangeByRank删除给定排序范围内的所有节点最坏 O(N2)O(N2)
zslGetRank返回目标元素在有序集中的排位最坏 O(N)O(N) 平均 O(logN)O(log⁡N)
zslGetElementByRank根据给定排位,返回该排位上的元素节点最坏 O(N)O(N) 平均 O(logN)

参考

  1. 书籍《Redis设计与实现》