• 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设计与实现》(感觉书上的图不太好理解,自己从网上找的图) 

  • 相关阅读:
    Core Java Interview Question Answer
    Anagrams
    Permutations II
    Minimum Window Substring
    工厂模式
    How do you design object oriented projects?
    What is Object Oriented Design? (OOD)
    Amazon Interview Question: Design an OO parking lot
    讨论一道求质数的面试题
    Substring with Concatenation of All Words
  • 原文地址:https://www.cnblogs.com/cuilichao/p/15712864.html
Copyright © 2020-2023  润新知