Redis 简单动态字符串SDS
2020-06-27 04:32
639 查看
Redis没有直接使用c语言传统的字符串表示(以空字符结尾的字符数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。
C字符串和SDS之间的区别进行了总结:
C字符串:
1.获取字符串长度的复杂度为o(N);
2.API是不安全的,可能会造成缓冲区溢出;
3.修改字符串长度N次必然需要指向N次内存重分配;
4.只能保存文本数据;
5.可以使用所有<string.h>库中的函数;
SDS:
1.获取字符串长度的复杂度为o(1);
2.API是安全的,不会造成缓冲区溢出;
3.修改字符串长度N次最多需要执行N次内存重分配;
4.可以保存文本或者二进制数据;
5.可以使用一部分<string.h>库中的函数;
struct sdshdr {
// buf 中已占用空间的长度
int len;
// buf 中剩余可用空间的长度
int free;
// 数据空间
char buf[];
};
获取sds实际保存的字符串长度
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->len;
}
sh是指向sdshdr结构体的指针
获取可用空间的长度
static inline size_t sdsavail(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->free;
}
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
// 根据是否有初始化内容,选择适当的内存分配方式
// T = O(N)
if (init) {
// zmalloc 不初始化所分配的内存
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
} else {
// zcalloc 将分配的内存全部初始化为 0
sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
}
// 内存分配失败,返回
if (sh == NULL) return NULL;
// 设置初始化长度
sh->len = initlen;
// 新 sds 不预留任何空间
sh->free = 0;
// 如果有指定初始化内容,将它们复制到 sdshdr 的 buf 中
// T = O(N)
if (initlen && init)
memcpy(sh->buf, init, initlen);
// 以 \0 结尾
sh->buf[initlen] = '\0';
// 返回 buf 部分,而不是整个 sdshdr
return (char*)sh->buf;
}
sds sdsMakeRoomFor(sds s, size_t addlen) {
struct sdshdr *sh, *newsh;
// 获取 s 目前的空余空间长度
size_t free = sdsavail(s);
size_t len, newlen;
// s 目前的空余空间已经足够,无须再进行扩展,直接返回
if (free >= addlen) return s;
// 获取 s 目前已占用空间的长度
len = sdslen(s);
sh = (void*) (s-(sizeof(struct sdshdr)));
// s 最少需要的长度
newlen = (len+addlen);
// 根据新长度,为 s 分配新空间所需的大小
if (newlen < SDS_MAX_PREALLOC)
// 如果新长度小于 SDS_MAX_PREALLOC
// 那么为它分配两倍于所需长度的空间
newlen *= 2;
else
// 否则,分配长度为目前长度加上 SDS_MAX_PREALLOC
newlen += SDS_MAX_PREALLOC;
// T = O(N)
newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
// 内存不足,分配失败,返回
if (newsh == NULL) return NULL;
// 更新 sds 的空余长度
newsh->free = newlen - len;
// 返回 sds
return newsh->buf;
}
转载于:https://www.cnblogs.com/liusikun/p/7210982.html
相关文章推荐
- Redis设计与实现——简单动态字符串(SDS)
- Redis源码剖析(十)简单动态字符串sds
- 小白的Redis学习(一)-SDS简单动态字符串
- 结合redis设计与实现的redis源码学习-2-SDS(简单动态字符串)
- redis 数据结构之和对象---简单动态字符串SDS(simple dynamic string)
- redis 系列3 简单动态字符串 SDS
- Redis内部数据结构详解之简单动态字符串(sds)
- Redis深入理解-数据结构篇(1)-简单动态字符串SDS
- Redis的简单动态字符串SDS、链表
- redis数据结构之一-简单动态字符串SDS
- Redis 数据结构之-简单动态字符串(SDS)
- redis数据结构-简单动态字符串(sds)
- 《Redis设计与实现》阅读:Redis底层研究之简单动态字符串SDS
- Redis源码剖析--简单动态字符串sds
- 图解Redis之数据结构篇——简单动态字符串SDS
- Redis源码分析(五)——简单动态字符串(sds)
- Redis数据结构之简单动态字符串SDS
- 图解Redis之数据结构篇——简单动态字符串SDS
- Redis源代码分析之五:简单动态字符串——Sds
- Redis -- 1、简单动态字符串(sds)