Redis学习笔记(四):跳跃表

Redis中的跳跃表(Skip List)被用作有序集合的底层实现,它以O(logN)的时间复杂度支持查找、插入和删除操作。每个跳跃表节点包含成员对象、分值、后退指针和多个层级的前进指针。Redis通过zskiplist结构持有跳表,提供了创建、释放、插入、删除、获取排位和元素等API。这些API确保了高效的数据操作。
摘要由CSDN通过智能技术生成

前言

跳跃表是一种以O(log N)期望时间支持查找、插入、删除操作的、有序的数据结构。

Redis使用跳跃表作为有序集合键的底层实现之一。

跳表的基本实现原理参考:《Skip lists: a probabilistic alternative to balanced trees》

1. Redis中的跳表实现

Redis的跳表由zskiplistNode, zskiplist两个数据结构定义。

跳跃表节点的实现如下,由redis.h/zskiplistNode定义:

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
    sds ele;							// 成员对象,唯一
    double score;						// 跳表按分值排序,不唯一
    struct zskiplistNode *backward;		// 后退指针,用于表尾到表头访问
    struct zskiplistLevel {
        struct zskiplistNode *forward;	
        unsigned long span;				// 跨度
    } level[];							// 层
} zskiplistNode;

Redis中跳表和普通跳表区别如下:

  • 添加span属性,表示跨度,用于计算排位。
  • 添加backward后退指针,用于表尾到表头访问节点,每次只能后退一个节点。
  • ele表示SDS对象,必须是唯一的,而普通跳表存储的值可以不唯一。
  • 添加score属性,表示分值,这是Redis跳表排序的依据,score的值允许重复。如score值相同,按ele字典序排列

Redis通过zskiplist结构来持有跳表:

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;	// 定位表头、表尾复杂度为O(1)
    unsigned long length;					// O(1)获取跳表长度
    int level;								// 层高,注意表头节点的层高不计算在内
} zskiplist;

2. 跳表API

API功能复杂度
zskiplist *zslCreate(void);创建跳表O(1)
void zslFree(zskiplist *zsl);释放跳表O(1)
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele);插入O(logN)
int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node);删除跳表O(logN)
unsigned long zslGetRank(zskiplist *zsl, double score, sds ele);返回给定节点的排位O(logN)
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);返回指定排位的节点O(logN)

参考资料

《Redis设计与实现》第5章 跳跃表

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pcj_888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值