redis中的zskiplist

redis中通过zskiplist 来表示一个跳跃表
typedef struct zskiplist {

    // 跳跃表的表头和表尾
    struct zskiplistNode *header, *tail;

    // 表示有跳跃表中有几个节点
    unsigned long length;

    // 跳跃表最大的层数
    int level;

} zskiplist;

//跳跃表的单个节点的数据结构如下所示:
typedef struct zskiplistNode {

    // 具体结构在后面
    robj *obj;
    // 节点的分值
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {

        // 前向指针
        struct zskiplistNode *forward;

        // 跨度
        unsigned int span;
    } level[];

} zskiplistNode;
#robj 结构体采用了c语言中的位域,为了节省内存
typedef struct redisObject {
 
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
     int refcount;
    void *ptr;

} robj;

从跳跃表的数据结构可以看出跳跃表是几个跳跃节点组成的list,组成跳跃表的节点之前根据里跳跃表的远近采取分层的方式,也就是所谓的level
本质上说跳跃表也是一种链表,其操作也就是链表的那几种常用操作。
zslCreate 用于新建一个新的跳跃表
zskiplist *zslCreate(void) {
    int j;
    zskiplist *zsl;

    // 分配空间
    zsl = zmalloc(sizeof(*zsl));

    // 初始化levl和length
    zsl->level = 1;
    zsl->length = 0;

	// 申请表头节点
    zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
    for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) {
	#表头节点赋值,这里ZSKIPLIST_MAXLEVEL 等于32 ,可见跳跃表最多有32个子表.这里一次性创建了32 个子表,然后分别最着32个子表初始化
        zsl->header->level[j].forward = NULL;
        zsl->header->level[j].span = 0;
    }
    zsl->header->backward = NULL;

    // 表尾赋值为null
    zsl->tail = NULL;

    return zsl;
}

zskiplistNode *zslCreateNode(int level, double score, robj *obj) {
    
    // 根据level 分配空间,可见跳跃表在创建的时候就已经申请了可以支持的最大内存空间
    zskiplistNode *zn = zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel));

    // 这里的obj 为null,score 为0
    zn->score = score;
    zn->obj = obj;

    return zn;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值