redis中使用sds来表示一个字符串,同时兼用c语言中的字符串,c语言中的字符串在redis中一般用作字符常量
其实现在E:\redis-3.0-annotated-unstable\redis-3.0-annotated-unstable\src\sds.h 和sds.c中
sds 的数据结构如下:
struct sdshdr {
// buf数组中已经占用的长度,这等于字符串的长度
int len;
// buf 数组中剩余的空间
int free;
// 数据空间
char buf[];
};
从 #define SDS_MAX_PREALLOC (1024*1024) 中可以知道sds中最多可以保存1M的数据
由于sds 表示的字符串和c语言中的不同,因此在sds中自定义了很多用于操作字符串的函数,我们几个简单的例子看看
sdsnewlen 这个函数形参init和字符串的长度initlen 重新申请一个sds,这里的形参initlen 正常情况下应该等于形参init的字符串传递
其源码分析如下:
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
// 根据形参init是否为null,来选择分配的方式,如果为null,则申请形参字符串形参initlen的长度,
//形参init 不为null的话,则通过zcalloc 申请全零的内存空间
if (init) {
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
} else {
sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
}
// 内存分配失败,返回
if (sh == NULL) return NULL;
// 设置sds中总长度len和free空间,这里free空间当然为零
sh->len = initlen;
sh->free = 0;
// 将字符串的内容复制到新申请的内存中
if (initlen && init)
memcpy(sh->buf, init, initlen);
// 以字符串的结尾添加结束符,从这里知道可以不用像c 语言那样,让用于在字符串结束添加结束符,而是sds提供的API 自动添加结束符
sh->buf[initlen] = '\0';
// 这里仅仅返回sds中字符串的指针而非整个sds 结构体指针
return (char*)sh->buf;
}
由于sds中本身就包含len表示字符串的长度,因此sdslen 求取sds字符串长度时直接返回成员变量len就行了.
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->len;
}
redis 中的sds
最新推荐文章于 2025-02-27 12:01:52 发布