Redis设计与实现——数据结构

redisObject保存对象的类型以及存储结构, type表示属于那种数据类型,encoding表示数据的存储方式,prt指向数据存储,如下表所示:
每种类型的数据都可能对用多种不同的存储结构
一、String类型
redisObject中的type值为REDIS_STRING
String类型的数据结构存储方式有三种:int、raw(即简单动态字符串)、embstr三种方式
如果存储的是整型数值,则使用int存储,encoding值为REDIS_ENCODING_INT
如果存储的是字符串并且长度大于32个字节,则使用SDS(简单动态字符串),encoding值为REDIS_ENCODING_RAW
一、简单动态字符串
特点:
  1. 记录长度,获取长度的复杂度为O(1)
  1. 字符串拼接时可自动扩容缓冲区,不会出现缓冲区溢出
  2. 提供空间与分配和惰性释放策略。空间分配策略: 当修改字符串后的长度len小于1MB,就会预分配和len一样长度的空间,即len=free;若是len大于1MB,free分配的空间大小就为1MB (现在数据结构已经变了)
  3. 二进制安全
使用场景
Redis中的key和string类型的value,存储结构为sds。文件:sis.h以及sds.c
数据结构定义:
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; // 字符串长度
    uint64_t alloc; // 分配的空间大小
    unsigned char flags; // 不知道干啥的
    char buf[]; // 保存字符串内容,’\0'结尾
};
sdshdr根据可以存储的字符串长度,分为:sdshdr8,sdshdr16,sdshdr32,sdshdr64。对应的数据成员len的类型分别为:uint8_t,uint16_t,uint32_t, uint64_t。也就是说可以支持的最大的字符串长度不同。
  • len:表示buf中以’\0’结尾的C风格字符串的长度。由于len指定了长度,所以不会string一样,遇到’\0’字符串就被截断。所以是二进制安全的。
  • alloc:指buf分配的空间大小。 对应的可用字节即alloc - len - 1。老版本的redis,sds中使用free字段表示剩余多少字节。
简单动态字符串中常用的一种类型:sds,实际上是 typedef char * sds。指向sdshdr的buf的头指针。
函数方法:
函数声明
说明
sds sdsnewlen(const void *init, size_t initlen)
使用init指向的字符串以及initlen初始化一个sds数据结构。
sds sdsempty(void)
初始化一个空的sdshdr结构。内部调用sdsnewlen(“”, 0)实现
sds sdsdup(const sds s)
复制一个sds。内部通过sdsnewlen(s, sdslen(s))实现
void sdsclear(sds s)
清空一个sds,内部通过将len设置为0,并将buf的第一个字节设置为’\0’实现。
sds sdsMakeRoomFor(sds s, size_t adelen)
扩容。
规则:
1.通过alloc - len计算剩余空间。
2.如果剩余空间大雨addlen,则表明剩余空间足够,此时直接返回sds
3.sds最大分配空间的大小为1MB,由SDS_MAX_PREALLOC宏定义。大小为1024 * 1024字节。如果新的长度小于1MB,则扩展为新长度的2倍。
4.如果新长度大于等于1MB,则扩展1MB。
5.如果新的长度未导致sdshdr类型的改变,则在原内存空间上扩展。
6.如果新的长度导致sdshdr类型变了,比如从sdshdr16变为sdshdr32了,则开辟新的内存空间,将原数据拷贝到新内存空间,释放原内存空间,返回新的内存空间。
sds sdsRemoveFreeSpace(sds s)
缩容
释放尾部的剩余空间
二、双端队列
文件:adlist.h和adlist.c
redis实现为双端链表。定义的数据结构主要有:列表节点,列表,迭代器。
列表节点定义
typedef struct listNode {
    struct listNode *prev;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值