redis-数据类型-有序集合-结构

154 阅读2分钟

redis-数据类型-有序集合-结构

基于 redis 5.08

有序集合zset,是由 跳跃表(zskiplist)+ 字典(dict)两种底层数据结构构成,

0、跳跃表高效支持,范围查询(zrangebyscore)

0、哈希表高效支持,单点查询(zscore-返回指定成员的score值)

结构

#define ZSKIPLIST_MAXLEVEL 64 /* Should be enough for 2^64 elements */
#define ZSKIPLIST_P 0.25      /* Skiplist P = 1/4 */


/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode { // 跳表节点的结构定义。
    sds ele; // 元素
    double score; // 权重值
    struct zskiplistNode *backward; // 后向指针(便于重跳表的尾节点进行倒序查找,每个跳表节点中还保存了,一个后向指针)
    struct zskiplistLevel { // 节点的level数组,保证了节点的,前向指针, 和, 跨度,
        struct zskiplistNode *forward;
        unsigned long span; // forward指针所指向节点 与 当前节点的 距离则为跨度。
    } level[];
} zskiplistNode;

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

typedef struct zset {
    dict *dict;
    zskiplist *zsl;
} zset;

zset结构图 (1).png

zet

  • dcit

用户存储 成员(member)和score,便于单点查询,O(1)的操作返回,member的score值

  • zskiplist

指向一个跳跃表

zskiplist

  • head

指向跳跃表的第一个节点,便于正序遍历操作

  • tail

指向跳跃表的最后一个节点,便于倒序遍历操作

  • length

跳跃表中节点的数量

  • level

层级,跳跃表中的,最大层级

zskiplistNode

  • ele

跳跃表中的元素

  • score

跳跃中元素的,分值。

  • backward

向后指针,指向 zskiplistNode,用户最后序遍历操作使用,

  • level[]

zskiplistNode *forward;

level数组中有一个向前的指针,

span:跨度,forward指针,指向目标节点的距离。到目标节点的span之和就是,目标节点的排名。

特点

  • 跳表(skiplist)一种多层的有序链表

  • 跳跃表节点可以有多个 forward节点,但是只有一个 backward节点

  • 跳跃表的最大层数为 16

  • 跳跃表中的所有节点,都是按照分值从小到大排序的,如果有分值相同的,则按照字母排序大小来进行排序

  • 跳跃表的层次都是随机生成的

  • 时间复杂度

    • 添加成员(zadd),O(logN)
    • 删除成员(zrem),O(logN)
    • 查询成员排名(zrank),O(logN)
    • 获取成员分值(zscore)O(1), 使用dict结构