动态长度字符串
本质就是typedef char *sds;
但是redis在sds的前面又增加了一个数据结构(不同长度数据结构不一样)
和c++的string不一样,这里的长度,容量和内存申请都是完全独立的
需要非常小心的手动维护
否则会出现数值和实际申请的内存不一致的情况
相关文件
- sds.h
- sds.c
相关概念
- 内存对齐
gcc的对齐是有优化的,按照结构体的最大位数进行对齐
__attribute__ ((__packed__))
的含义是取消gcc的对齐,数据实际占用多少就用多少内存
没有空空间 - 宏中
#
的含义#
,将参数按字面表现转化为字符串##
,字符串拼接
主要函数
外部调用
- 创建字符串
sds sdsnew(const char *init);
- 创建空字符串
sds sdsempty(void);
- 复制字符串
sds sdsdup(const sds s);
- 释放字符串
void sdsfree(sds s);
- 连接字符串
sds sdscat(sds s, const char *t);
- 复制字符串到已有字符串
sds sdscpy(sds s, const char *t);
内部调用
- 扩展字符串容量
sds sdsMakeRoomFor(sds s, size_t addlen);
- 维护字符串新增长度
void sdsIncrLen(sds s, int incr);
- 将容量设置为长度,节省内存
sds sdsRemoveFreeSpace(sds s);
- 获取字符串容量(包含结构体长度)
size_t sdsAllocSize(sds s);
- 获取字符串实际结构指针
void *sdsAllocPtr(sds s);
- 获取字符串长度
static inline size_t sdslen(const sds s)
- 获取字符串剩余空间
static inline size_t sdsavail(const sds s)
- 变更字符传长度记录
static inline void sdssetlen(sds s, size_t newlen)
- 增加字符串长度记录
static inline void sdsinclen(sds s, size_t inc)
- 获取字符串容量
static inline size_t sdsalloc(const sds s)
- 变更字符串容量记录
static inline void sdssetalloc(sds s, size_t newlen)
数据结构
- 数据记录是使用
char*
- 所有的
sdshdr
结尾都使用char buf[]
动态数组做结尾,不占用内存 flags
字段的低3位是记录改字符串的数据结构类型sdshdr5
的高5位记录字符串长度- 非
sdshdr5
的数据结构len
是长度(实际使用的连续可用内存的大小) alloc
是容量(实际申请的可用连续内存的大小)
1 | typedef char *sds; |
函数分析
#define SDS_HDR_VAR(T,s)
功能
获取sds
字符串的原始结构体指针sh
源码
1 |
#define SDS_HDR(T,s)
功能
将sds
字符串转换为原始结构体指针
源码
1 |
sds sdsnewlen(const void *init, size_t initlen);
功能
1 | /* Create a new sds string with the content specified by the 'init' pointer |
sds sdsempty(void);
功能
创建空字符串
常用于复制,连接字符串
源码
1 | sds sdsempty(void) { |
sds sdsnew(const char *init);
功能
根据字符串创建一个sds
源码
1 | sds sdsnew(const char *init) { |
sds sdsdup(const sds s);
功能
复制字符串
源码
1 | sds sdsdup(const sds s) { |
void sdsfree(sds s);
功能
释放字符串空间
源码
1 | void sdsfree(sds s) { |
void sdsclear(sds s);
功能
清空字符串内容
申请的内存和结构不动
后续使用这个字符串不需要重新申请内存
源码
1 | void sdsclear(sds s) { |
sds sdsMakeRoomFor(sds s, size_t addlen);
功能
扩大字符串的容量
为连接/扩展字符串做准备
源码
1 | sds sdsMakeRoomFor(sds s, size_t addlen) { |
sds sdsRemoveFreeSpace(sds s);
功能
清空字符串结构的容量冗余
使容量等于字符串长度
节省内存使用
源码
1 | /* Reallocate the sds string so that it has no free space at the end. The |
sds sdsgrowzero(sds s, size_t len);
功能
从有效字符串结尾开始,直到len
位置
初始化所有数据为0
源码
1 | /* Grow the sds to have the specified length. Bytes that were not part of |
sds sdscatlen(sds s, const void *t, size_t len);
功能
字符串连接
源码
1 | /* Append the specified binary-safe string pointed by 't' of 'len' bytes to the |
int sdsll2str(char *s, long long value);
功能
将数字按字面值转化为字符串
源码
1 | /* Helper for sdscatlonglong() doing the actual number -> string |
sds sdsfromlonglong(long long value);
功能
将数字转化为sds
源码
1 | sds sdsfromlonglong(long long value) { |
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
功能
字符串格式化连接
源码
1 | /* Like sdscatprintf() but gets va_list instead of being variadic. */ |
sds sdscatprintf(sds s, const char *fmt, ...);
功能
字符串格式化连接
源码
1 | /* Append to the sds string 's' a string obtained using printf-alike format |
sds sdscatfmt(sds s, char const *fmt, ...);
功能
字符串格式化连接(高效简略版)
源码
1 | /* This function is similar to sdscatprintf, but much faster as it does |
sds sdstrim(sds s, const char *cset);
功能
去除字符串两边需要过滤的字符集
源码
1 | /* Remove the part of the string from left and from right composed just of |
void sdsrange(sds s, int start, int end)
功能
截取字符串
支持负数倒叙定位
源码
1 | /* Turn the string into a smaller (or equal) string containing only the |
void sdstolower(sds s);
功能
所有字符变为小写
源码
1 | /* Apply tolower() to every character of the sds string 's'. */ |
void sdstoupper(sds s);
功能
所有字符变为大写
源码
1 | /* Apply toupper() to every character of the sds string 's'. */ |
int sdscmp(const sds s1, const sds s2);
功能
比较两个字符串的大小
源码
1 | /* Compare two sds strings s1 and s2 with memcmp(). |
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
功能
将字符串按照sep拆分为字符数组
源码
1 | /* Split 's' with separator in 'sep'. An array |
void sdsfreesplitres(sds *tokens, int count);
功能
整体释放字符数组
源码
1 | /* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */ |
sds sdsjoin(char **argv, int argc, char *sep);
功能
字符数组连接为一个字符串
连接符为sep
源码
1 | /* Join an array of C strings using the specified separator (also a C string). |