zoukankan      html  css  js  c++  java
  • redis数据结构跳跃表

    跳跃表(skiplist)是一种有序数据结构, 它通过在每个节点中维持多个指向其他节点的指针, 从而达到快速访问节点的目的。

    跳跃表支持平均 O(\log N) 最坏 O(N) 复杂度的节点查找, 还可以通过顺序性操作来批量处理节点。

    跳跃表的实现

    redis 的跳跃表由 zskiplistNode 和 zskiplist 两个结构定义,zskiplistNode 结构用于表示跳跃表节点,zskiplist 结构则用于保存跳跃表节点的相关信息

    跳跃表节点

    typedef struct zskiplistNode {
        // 后退指针
        struct zskiplistNode *backward;
    // 分值 double score; // 成员对象 robj *obj; // struct zskiplistLevel { // 前进指针 struct zskiplistNode *forward; // 跨度 unsigned int span; } level[]; } zskiplistNode;
    • 层:跳跃表节点的 level 数组可以包含多个元素, 每个元素都包含一个指向其他节点的指针, 程序可以通过这些层来加快访问其他节点的速度, 一般来说, 层的数量越多, 访问其他节点的速度就越快。每次创建一个新跳跃表节点的时候, 程序会随机生成一个介于 1 和 32 之间的值作为 level 数组的大小, 这个大小就是层的“高度”。
    • 前进指针: 用于从表头向表尾方向访问节点
    • 跨度:用于记录两个节点之间的距离,两个节点之间的跨度越大, 它们相距得就越远。指向 NULL 的所有前进指针的跨度都为 0 , 因为它们没有连向任何节点。
    • 后退指针:用于从表尾向表头方向访问节点:,跟可以一次跳过多个节点的前进指针不同, 因为每个节点只有一个后退指针, 所以每次只能后退至前一个节点。
    • 分值:是一个 double 类型的浮点数, 跳跃表中的所有节点都按分值从小到大来排序。
    • 成员:是一个指针, 它指向一个字符串对象, 而字符串对象则保存着一个 SDS 值。

    zskiplist结构

    虽然仅靠多个跳跃表节点就可以组成一个跳跃表,但通过使用一个zskiplist结构来持有这些节点, 程序可以更方便地对整个跳跃表进行处理, 比如快速访问跳跃表的表头节点和表尾节点, 又或者快速地获取跳跃表节点的数量(也即是跳跃表的长度)等信息。

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

    跳表创建过程

     

     跳表查询过程

    跳跃表API

     

    本文参考《Redis设计与实现》(感觉书上的图不太好理解,自己从网上找的图) 

  • 相关阅读:
    【Qt开发】01-第一个Qt程序Hello World!
    Git使用总结(三):协同开发常见冲突
    公钥、私钥、数字签名、数字证书、对称与非对称算法、HTTPS
    通俗理解TCP的三次握手
    Flink安装极简教程-单机版
    程序员工资那些事!
    vim实战:插件安装(Vundle,NerdTree)
    Git使用总结(二):分支管理
    Git使用总结(一):简介与基本操作
    C++11并发编程:多线程std::thread
  • 原文地址:https://www.cnblogs.com/cuilichao/p/15712864.html
Copyright © 2011-2022 走看看