Redis的数据结构与对象——跳跃表

rookie_yuqi · · 761 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

引言:跳跃表是一种有序数据结构,它通过在每个节点中维持多个执行其他节点的指针,从而达到快速访问节点的目的。跳跃表的查询速度可以和平衡书相媲美,平均时间复杂度O(logN),最坏O(N),但实现起来比平衡树要简单很多。

跳跃在redis中只有两个地方使用,一个是有序集合(zset还使用了字典加跳跃表实现),另一个是集群节点中用作内部数据结构。

一、实现

跳跃表由redis.h/zskiplistNode和redis.h/zskiplist两个结构体实现

1.1、跳跃表节点

struct zskiplistNode{

    struct zskiplistNode *backward;// 后退指针

    double score;// 分值

    robj *obj;// 成员对象

    struct zskiplistLevel { // 层;

         struct zskiplistNode *forward; //前进指针

        unsigned int span; //跨度

    } leve[];

}

level: 该数组可以包含多个元素,每个元素都包含一个前进指针,程序可以通过这些层来加快访问其他节点的速度,一般来说,层数越多,节点访问速度越快。

forward:用于从表头向表尾方向访问节点

span:跨度,用于记录两个节点之间的距离。跨度实际上是用于排位的,在查找某个节点的时候,将沿途访问过的所有层的跨度全部加起来,就是目标节点在跳跃表中的排位。

barkward:用于从表尾向表头方向访问节点

score和obj:score是浮点数,用来排序。obj是一个指针,指向的是字符串对象,注意:一定是字符串对象,这个字符串对象保存的是SDS值,也就是说跳跃表的值是SDS。其中,obj一定是唯一的,但是分值可以相同。如果分值相同,就按照字典顺序排序,升序。

1.2、跳跃表

struct zskilist{

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

    unsigned long length;// 节点数量

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

}




二、注意点

跳跃表的值robj一定是个字符串对象,说明redis的跳跃表只能保存字符串,zset也只能保存字符串,这个值必须是唯一的。score可以相同。

三、番外

golang实现跳跃表:https://www.jianshu.com/p/400d24e9daa0?from=timeline&isappinstalled=0


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:rookie_yuqi

查看原文:Redis的数据结构与对象——跳跃表

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

761 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传