redis对象编码源码阅读——列表对象编码与创建

18 篇文章 0 订阅
17 篇文章 1 订阅

redis对象编码源码阅读——列表对象编码与创建

1. 列表对象的编码类型

类型编码对象
REDIS_LISTREDIS_ENCODING_ZIPLIST使用压缩列表对象实现的列表对象
REDIS_LISTREDIS_ENCODING_LINKEDLIST使用双端链表实现的列表对象

摘自《Redis设计与实现》第63页

2. 双端链表对象的创建

robj *createListObject(void) {
    list *l = listCreate();
    robj *o = createObject(REDIS_LIST,l);
    listSetFreeMethod(l,decrRefCountVoid);
    o->encoding = REDIS_ENCODING_LINKEDLIST;
    return o;
}

3. 压缩列表对象的创建

robj *createZiplistObject(void) {
    unsigned char *zl = ziplistNew();
    robj *o = createObject(REDIS_LIST,zl);
    o->encoding = REDIS_ENCODING_ZIPLIST;
    return o;
}

4. 两种编码的转换

void listTypeConvert(robj *subject, int enc) {
    // 类似于 c++ 中的迭代器
    listTypeIterator *li;
    listTypeEntry entry;
    redisAssertWithInfo(NULL,subject,subject->type == REDIS_LIST);

    if (enc == REDIS_ENCODING_LINKEDLIST) {
        list *l = listCreate();
        listSetFreeMethod(l,decrRefCountVoid);

        /* listTypeGet returns a robj with incremented refcount */
        // 类似于 c++ 中的赋初值: li = subject.begin()
        // 因为这里 index = 0,所以是 begin()
        li = listTypeInitIterator(subject,0,REDIS_TAIL);
        // 因为 ListTypeIterator 是不知道 List 的具体编码的,具体的编码被封装起来了
        // 所以在求 nextNode 的时候使用了一个中间类型 listTypeEntry
        // 把 nextNode 求解出来之后,再赋值到最简单的链表 list 中
        while (listTypeNext(li,&entry)) listAddNodeTail(l,listTypeGet(&entry));
        // 释放迭代器的空间
        listTypeReleaseIterator(li);

        subject->encoding = REDIS_ENCODING_LINKEDLIST;
        zfree(subject->ptr);
        subject->ptr = l;
    } else {
        redisPanic("Unsupported list conversion");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值