redis 源码intset(intset.c/intset.h)

redis 源码intsetintset是集合键的底层实现之一, 保存的元素是有序的。redis中intset是一个整数集合, 只能存储整数类型的数据, 可以是16位, 32位, 或者是64位, 是以升序排列的数组进行保存数据,下面会介绍具体数据结构和对其操作过程.数据结构typedef struct intset { // 编码方式 uint32_t encoding;...
摘要由CSDN通过智能技术生成

redis 源码intset

intset是集合键的底层实现之一, 保存的元素是有序的。

redis中intset是一个整数集合, 只能存储整数类型的数据, 可以是16位, 32位, 或者是64位, 是以升序排列的数组进行保存数据,下面会介绍具体数据结构和对其操作过程.

数据结构

typedef struct intset {
   
    // 编码方式
    uint32_t encoding;

    // 集合包含的元素数量
    uint32_t length;

    // 保存元素的数组
    int8_t contents[];

} intset;

**个人理解encoding:**如果想读懂源码,必须读懂这一段

因为redis中intset是一个整数集合, 只能存储整数类型的数据, 可以是16位, 32位, 或者是64位,但是存元素的数组类型是int8_t,所以需要encoding表明数组中存的元素是多少位的,不然存取元素会出错。

这里需要理解编解码函数

void memrev16(void *p) {
   
    unsigned char *x = p, t;

    t = x[0];
    x[0] = x[1];
    x[1] = t;
}

/* Toggle the 32 bit unsigned integer pointed by *p from little endian to
 * big endian */
void memrev32(void *p) {
   
    unsigned char *x = p, t;

    t = x[0];
    x[0] = x[3];
    x[3] = t;
    t = x[1];
    x[1] = x[2];
    x[2] = t;
}

/* Toggle the 64 bit unsigned integer pointed by *p from little endian to
 * big endian */
void memrev64(void *p) {
   
    unsigned char *x = p, t;

    t = x[0];
    x[0] = x[7];
    x[7] = t;
    t = x[1];
    x[1] = x[6];
    x[6] = t;
    t = x[2];
    x[2] = x[5];
    x[5] = t;
    t = x[3];
    x[3] = x[4];
    x[4] = t;
}

uint16_t intrev16(uint16_t v) {
   
    memrev16(&v);
    return v;
}

uint32_t intrev32(uint32_t v) {
   
    memrev32(&v);
    return v;
}

uint64_t intrev64(uint64_t v) {
   
    memrev64(&v);
    return v;
}

其实可以看出来,编解码只是把值按字符型reverse一下。整个结构体中,不仅仅要使用encoding处理数值,还要用encoding处理length。至于为什么要这样做,是因为
简单来说,在redis的RDB持久化方式中,ziplists, intsets等是直接被写到文件中去的,所以这要求他们在内存中是大小端中性(endian-neutral),而大部分环境是小端法的,于是对于这些压缩的数据结构,redis总是采取小端法的方式来存放字节,那么对于大端法的机器来说,想要得到正确的数,便需要端转换。需要注意的是,反转的仅仅是作为参数传入的在栈上的字节,对于结构体自身的字节并未发生改变。

创建intset函数

intset *intsetNew(void) {
   

    // 为整数集合结构分配空间
    intset *is = zmalloc(sizeof(intset));

    // 设置初始编码
    is->encoding = intrev32ifbe(INTSET_ENC_INT16);

    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值