赞
踩
当Redis需要的不仅仅是一个字面量,而是一个可以被修改的字符串值时,Redis就会使用SDS来表示字符串。包含字符串值的键值对在底层都是SDS实现的。
sdshdr结构表示一个SDS值
struct sdshdr {
// 记录 buf 数组中已使用字节的数量
// 等于 SDS 所保存字符串的长度
int len;
// 记录 buf 数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
};
内存分配策略:
当 SDS 的 API 对一个 SDS 进行修改, 并且需要对 SDS 进行空间扩展的时候, 程序不仅会为 SDS 分配修改所必须要的空间, 还会为 SDS 分配额外的未使用空间。
其中, 额外分配的未使用空间数量由以下公式决定:
SDS遵循 C 字符串以空字符结尾的惯例,这是为了让那些保存文本数据的 SDS 可以重用一部分
链表是列表键的底层实现之一,当一个列表键包含了数量比较多的元素, 又或者列表中包含的元素都是比较长的字符串时, Redis 就会使用链表作为列表键的底层实现。
每个链表节点使用一个 adlist.h/listNode 结构来表示:
typedef struct listNode {
// 前置节点
struct listNode *prev;
// 后置节点
struct listNode *next;
// 节点的值
void *value;
} listNode;
使用 adlist.h/list 来持有链表:
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;
参考资料
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。