《Redis设计与实现》阅读笔记——数据结构与对象

简单动态字符串

redis的底层是C语言,但是没有简单的使用C语言传统的以空字符结尾的字符数组表示字符串。使用的是SDS表示字符串。

struct sdshdr {
	//记录buf数组中已经使用的字节数量,等于SDS保存字符串长度(去除了结尾空字符串)
	int len;
	//记录buf中未使用的字节的数量
	int free;
	//字节数组,保存字符串
	char buff[];
}

1.1 SDS与C字符串区别

常数复杂度获取字符串长度

杜绝缓冲区溢出

对buff进行操作的时候,若剩余空间不够,则先进行扩容再进行写入。

减少修改字符串时带来的内存重分配次数

修改N次字符串长度,最多执行N次内存重分配
redis作为数据库,数据可能会被频繁修改,而且速度要求很严苛。所以,若每次修改字符串的时候,都要进行内存重分配,就很浪费。

  • 一:空间预分配:对SDS修改时需要空间扩展

    • 扩展后的SDS的长度 小于1MB,则会分配一个和len属性相同大小的未使用空间。例如修改之后len变成13字节,则buff的实际长度是13+13+1=27字节(额外的字节保存空字节)
    • 扩展后的SDS的长度 大于1MB,则会分配1MB未使用空间。例如修改之后len变成30MB,则buff的实际长度是30MB+1MB+1byte(额外的字节保存空字节)
  • 二:惰性空间释放:用于优化SDS的字符串缩短操作

    • 不会立刻使用内存重分配来回收缩短后多出来的字节。只会在有需要的时候释放。

二进制安全

为了确保redis可以存储各种数据,所以用sds,防止有些特殊字符无法展示。

兼容部分C字符串函数

链表

C语言没有内置实现链表,redis自己实现,通常用于redis中的列表键,发布与订阅,慢查询,监视器等。

typedef struct listNode {
	struct listNode *prev;
	struct listNode *next;
	//节点的值
	void *value
}listNode;

typedef struct list {
	listNode *head;
	//尾节点
	listNode *tail;
	//链表包含的节点数量
	unsigned long len;
	//节点值复制函数
	void *(*dup) (void *ptr);
	// 节点值释放函数
	void (*free) (void *ptr);
	// 节点值对比函数
	int (*match) (void *ptr, void *key);
}list;

字典

用于保存键值对的抽象数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值