redis学习笔记(6)---压缩列表ziplist

压缩列表ziplist是Redis用于存储列表和哈希键的高效数据结构,适用于小数据量且元素为小整数或短字符串的情况。文章介绍了ziplist的内存布局、节点定义、创建过程、元素加入、查找操作及API,解析了ziplist如何节省内存并提供操作效率。
摘要由CSDN通过智能技术生成

ziplist

  压缩列表是列表键和哈希键的底层实现之一。
  当一个列表键只包含少量表项,并且每个列表项要么是小整数,要么是较短的字符串 ,那么redis就会使用压缩列表来作为列表键的底层实现。
  当一个哈希键只包含少量key-value对,且每个key-value对的key和value要么是小整数,要么是较短字符串,那么redis就会使用ziplist作为哈希键的底层实现。

ziplist的实现:

  ziplist的内存布局如下所示:
  这里写图片描述

  • zlbytes:4字节,记录整个压缩列表占用内存的字节数
  • zltail:4字节,记录压缩列表尾部节点距离起始地址的偏移量
  • zllen:2字节,记录压缩列表包含的节点数量
  • entry:不定,列表中的每个节点
  • zlend:1字节,特殊值0xFF,标记压缩列表的结束

  因此通过下面的宏定义可以非常方便的求出各个字段的值

#define ZIPLIST_BYTES(zl)       (*((uint32_t*)(zl)))
#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t))))
#define ZIPLIST_LENGTH(zl)      (*((uint16_t*)((zl)+sizeof(uint32_t)*2)))
#define ZIPLIST_HEADER_SIZE     (sizeof(uint32_t)*2+sizeof(uint16_t))
#define ZIPLIST_ENTRY_HEAD(zl)  ((zl)+ZIPLIST_HEADER_SIZE)
#define ZIPLIST_ENTRY_TAIL(zl)  ((zl)+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)))
#define ZIPLIST_ENTRY_END(zl)   ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1)

  一个简单的ziplist示意图如下:  
  这里写图片描述
  zlbytes为0x50,表示压缩列表一共占用了0x50=80字节,其中zltail指示最后一个节点距离起始地址的偏移量为0x3C=60字节,因此p+60就为最后一个节点的起始地址,zllen=3表示列表中一共有3个节点。

ziplist节点定义如下:

typedef struct zlentry {
    unsigned int prevrawlensize, prevrawlen;
    unsigned int lensize, len;
    unsigned int headersize;
    unsigned char encoding;
    unsigned char *p;
} zlentry;
  • prevrawlen:前置节点的长度
  • prevrawlensize:编码 prevrawlen 所需的字节大小
  • len:当前节点的长度
  • lensize:编码 len 所需的字节大小
  • headersize:当前节点 header 的大小,等于 prevrawlensize + lensize
  • encoding:当前节点值所使用的编码类型
  • p:指向当前节点的指针

ziplist的创建

#define ZIPLIST_HEADER_SIZE     (sizeof(uint32_t)*2+sizeof(uint16_t))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值