Redis基础数据结构之 ziplist 压缩列表 源码解读

ziplist 是什么?

压缩列表,内存紧凑的数据结构,占用一块连续的内存空间。一个 ziplist 可以包含多个节点(entry), 每个节点可以保存一个长度受限的字符数组(不以 \0 结尾的 char 数组)或者整数, 包括:

  • 字符数组
    • 长度小于等于 63 (2^6-1)字节的字符数组
    • 长度小于等于 16383 (12^14-1) 字节的字符数组
    • 长度小于等于 4294967295 (2^32-1)字节的字符数组
  • 整数
    • 4 位长,介于 0 至 12 之间的无符号整数
    • 1 字节长,有符号整数
    • 3 字节长,有符号整数
    • int16_t 类型整数
    • int32_t 类型整数
    • int64_t 类型整数
    • Redis 哪些数据结构使用了 ziplist?
    • 哈希键
    • 列表键
    • 有序集合键

ziplist 特点

  • 优点
    • 节省内存
  • 缺点
    • 不能保存过多的元素,否则访问性能会下降
    • 不能保存过大的元素,否则容易导致内存重新分配,甚至引起连锁更新

ziplist 数据结构

// ziplist 中的元素,是 string 或者 integer
typedef struct {
   
   
    // 如果元素是 string,slen 就表示长度
    unsigned char *sval;
    unsigned int slen;
    // 如果是 integer,sval 是 NULL,lval 就是 integer 的值
    long long lval;
} ziplistEntry;

在这里插入图片描述

为了方便地取出 ziplist 的各个域以及一些指针地址, ziplist 模块定义了以下宏:

// 取出 zlbytes 的值
#define ZIPLIST_BYTES(zl)       (*((uint32_t*)(zl)))

// 取出 zltail 的值
#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t))))

// 取出 zllen 的值
#define ZIPLIST_LENGTH(zl)      (*((uint16_t*)((zl)+sizeof(uint32_t)*2)))

// 返回 ziplist header 部分的长度,总是固定的 10 字节
#define ZIPLIST_HEADER_SIZE     (sizeof(uint32_t)*2+sizeof(uint16_t))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休居士

感谢您的支持,我会继续努!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值