redis整数集合升级扩容(代码学习)

本文探讨了Redis中整数集合在遇到int64_t类型整数时的升级过程,包括类型判断、扩容及填数步骤。在升级过程中,首先检查新增值类型,然后通过`intsetResize`进行扩容,再将数据后移。新增数时,若不改变集合类型则无需升级,但仍需扩容并插入新数。扩容使用`realloc`,移位借助`memmove`以避免覆盖原有内容。实验发现,分配空间时应使用calloc而非malloc。
摘要由CSDN通过智能技术生成

redis整数集合有固定的数据类型,比如是整数集合是int32_t类型,新增一个int64_t类型的整数,就需要对整个集合进行升级。

redis的程序值得学习的地方太多。

一、升级

升级分为两步:扩容  +  填数

1.1 新增值的类型判断

static uint8_t _intsetValueEncoding(int64_t v) {
    if (v < INT32_MIN || v > INT32_MAX)
        return INTSET_ENC_INT64;
    else if (v < INT16_MIN || v > INT16_MAX)
        return INTSET_ENC_INT32;
    else
        return INTSET_ENC_INT16;
}

C中int类型是32位的,范围是 INT32_MIN=-2147483648到 INT32_MAX=2147483647 。

1.2 扩容

进行扩容在原有空间上增加1个新增数的位置

is = intsetResize(is,intrev32ifbe(is->length)+1);

static intset *intsetResize(intset *is, uint32_t len) {
    uint32_t size = len*intrev32ifbe(is->encoding);
    is = zrealloc(is,sizeof(intset)+size);
    return is;
}

1.3 填数

数据依次后移

while(length--)
    _intsetSet(is,length+prepend,_intsetGetEncoded(is,length,curenc));

static void _intsetSet(intset *is, int pos, int64_t value) {//按照新类型进行填数
    uint32_t encoding = intrev32ifbe(is->encoding);

    if (encoding == INTSET_ENC_INT64) {
        ((int64_t*)is->contents)[pos] = value;
        memrev64ifbe(((int64_t*)is->contents)+pos);
    } else if (encoding == INTSET_ENC_INT32) {
        ((int32_t*)is->contents)[pos] = value;
        memrev32ifbe(((int32_t*)is->contents)+pos);
    } else {
        ((int16_t*)is->contents)[pos] = value;
        m
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值