1 数据结构说明
Sorted Set 的主要数据结构之一,负责根据元素的分数进行排序和提供快速访问。
主要方法在 t_zset.c 文件中
2 数据结构
/* 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;
typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist;
typedef struct zset {
dict *dict;
zskiplist *zsl;
} zset;
zskiplistNode
结构体
sds ele
: 一个动态字符串(Simple Dynamic String),用于存储节点的实际元素值。double score
: 一个双精度浮点数,表示节点的分数,这是用来排序的关键值。struct zskiplistNode *backward
: 指向当前节点的前一个节点的指针,用于在跳跃表中反向遍历。struct zskiplistLevel level[]
: 这是一个变长数组,每个元素都是一个zskiplistLevel
结构体,代表跳跃表的一个层级。数组的大小取决于跳跃表的层数。
zskiplistLevel
结构体
struct zskiplistNode *forward
: 指向当前层级下一个节点的指针。unsigned long span
: 表示从当前节点到forward
节点之间跨越了多少个节点(包括forward
节点本身)。
zskiplist
结构体
struct zskiplistNode *header, *tail
: 分别指向跳跃表的头节点和尾节点。头节点通常是一个虚拟节点,它不存储实际的数据。unsigned long length
: 记录跳跃表中的节点数量。int level
: 当前跳跃表的最大层数。
zset
结构体
dict *dict
: 一个字典,用于存储元素到分数的映射,并保证元素的唯一性。字典的键是元素(ele
),值是分数(score
)。zskiplist zsl
: 一个跳跃表,用于根据分数对元素进行排序。跳跃表中的每个节点都包含了一个元素及其对应的分数。
3 核心代码
zslCreate 创建跳表
zskiplist *zslCreate(void) {
int j;
zskiplist *zsl;
// 分配内存给 zskiplist 结构体
zsl = zmalloc(sizeof(*zsl));
// 初始化跳跃表的层数为 1
zsl->level = 1;
zsl->length = 0;
// 创建一个虚拟头节点,其层级为 ZSKIPLIST_MAXLEVEL,分数为 0,元素为 NULL
zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
// 初始化头节点的每一层
for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) {
zsl->header->level[j].forward = NULL;
zsl->header->level