一个lua版的zset数据结构实现

本文介绍了使用Lua实现Redis中的Zset数据结构,利用SkipList(跳跃表)和Dict来实现有序集合。详细讲解了结构定义、SkipList的高效性能原因、字典在Zset中的作用,以及枚举器的设计,同时提到了开源代码及未来计划完善的功能,如相同分数的结点处理和批量删除操作。
摘要由CSDN通过智能技术生成

redis里的zset是一种有序集合,从逻辑上,可以理解为在集合的基础上,为每一个成员增加了分数字段,分数是一种浮点数值,并可以相同,它们按序排列起来。它能对分数在增,删,查找上都能提供对数时间复杂度的操作。

redis里的zset是利用一个skiplist和一个dict实现的,其中关键数据结构就是skiplist,跳跃表。

skiplist的原理和基本实现网上有很多,不再啰嗦。基于zset的需求,会有稍微的改进。

1,结构定义

typedef struct skiplistnode {
    double score;
    int member; /* (1) */
    struct skiplistnode *backward; /* (2) */
    struct skiplistforward {
        struct skiplistnode *ptr;
        unsigned long span; /* (3) */
    } forward[];
} skiplistnode;

typedef struct skiplist {
    int level;
    unsigned long length;
    struct skiplistnode *header, *tail;
} skiplist;

基本参考了redis的定义,其中member为什么是int(1),是用来放luaL_ref的ref值,所有放在容器里的数据都会先引用,然后记在这个C结构里,所以它可以记任何lua类型:函数,对象等。那个backward(2),是用反向遍历结点,比如zrevrange*这类操作。那个span的含义是(3),当前那一层的下一跳ptr距离本结构的距离,这是为了实现rank计算排名等相关操作的,为什么要这样定义,这样可以在只有局部结点变化时,需要修改的span值比较少,而且也比较容易实现各种计数操作。

2,为什么skiplist有平均很好的性能

具体有严格的证明,我只写下我自己的理解。本质上它就是一个list,只不过每个结点有一个层级level,任何结构的层级都是随机生成,像这样:

int
sl_randomlevel() {
    int level = 1;
    while (random() * 2 < RAND_MAX)
        level++;
    return level > MAX_SKIP_LEVEL ? M
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值