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;
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结构