Redis自定义动态字符串(sds)模块(一)
Redis开发者在开发过程中没有使用系统的原始字符串,而是使用了自定义的sds字符串,这个模块的编写是在文件:sds.h和sds.c文件中。Redis自定义的这个字符串好像也不是很复杂,远不像nginx自定义的一样复杂,但也存在一些问题。
在.h文件中定义了一个新的类型和一个结构体分别是:
typedef char *sds;//定义了sds的字符串类型,使用的仍是字符串指针,只是多了个头部,具体定义见sdshdr。 //动态字符串,数组的长度是可变的。
struct sdshdr {
unsigned int len;//记录当前串的长度。
unsigned int free;//记录剩余的有效长度。
char buf[];//真正的字符串位置。
};
先说两个小的内联函数,这个俩函数:
//在本系统内所有的字符串都必须sds类型,否则用这个函数求取长度将会出错,还有一个问题,在修改了字符串的内容之后如果长度变了,要刷新头部的了len和free。否则会造成实际长度和真是长度不一致问题。
static inline size_t sdslen(const sds s)
{
//求取长度时,参数为字符串的地址,按照SDS的约定,字符串前面是动态数组的头部,将给定的地址
//按照头部的长度前移一定长度,就可按照结构体直接获取到长度
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->len;
} //检查字符串的空闲部分大小
static inline size_t sdsavail(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->free;
}
sds整体接口函数一览:
//创建一个指定内容的sds字符串,参数为内容和长度
sds sdsnewlen(const void *init, size_t initlen);
//创建一个指定内容的字符串,会调用上一个函数
sds sdsnew(const char *init);
//返回一个长度为0的sds字符串
sds sdsempty(void);
//返回sds字符串的长度
size_t sdslen(const sds s);
//复制一个已经sds字符串,会调用sdsnewlen
sds sdsdup(const sds s);
//获取一个sds字符串的剩余空间
void sdsfree(sds s);
//sds字符串是否有效,如果字符串已经释放,再调用可能会出错。
size_t sdsavail(const sds s);
//增长字符串
sds sdsgrowzero(sds s, size_t len);
//扩展sds长度,新的部分用指定字符填充
sds sdscatlen(sds s, const void *t, size_t len);
//扩展sds长度,扩展的长度和填充的值的长度一样
sds sdscat(sds s, const char *t);
//字符串拼接,将第二个拼接到第一个后面
sds sdscatsds(sds s, const sds t);
//将string串拼接入某个sds的后面,后面参数为string的长度
sds sdscpylen(sds s, const char *t, size_t len);
//调用上面的函数
sds sdscpy(sds s, const char *t); sds sdscatvprintf(sds s, const char *fmt, va_list ap);
#ifdef __GNUC__
sds sdscatprintf(sds s, const char *fmt, ...)
__attribute__((format(printf, , )));
#else
sds sdscatprintf(sds s, const char *fmt, ...);
#endif sds sdscatfmt(sds s, char const *fmt, ...);
//字符串剪切函数,从串中去掉某些字符
sds sdstrim(sds s, const char *cset);
//字符串剪切函数
void sdsrange(sds s, int start, int end);
//刷新字符串的长度,字符串真实的长度和len可能不一致
void sdsupdatelen(sds s);
//清空字符串,只是清空了长度,没有释放内存,可以继续使用
void sdsclear(sds s);
//串比较函数
int sdscmp(const sds s1, const sds s2);
//
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
void sdsfreesplitres(sds *tokens, int count);
//转换成小写
void sdstolower(sds s);
//转换成大写
void sdstoupper(sds s);
//将longlong类型转为sds字符串
sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, const char *p, size_t len);
sds *sdssplitargs(const char *line, int *argc);
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
sds sdsjoin(char **argv, int argc, char *sep); /* Low level functions exposed to the user API */
sds sdsMakeRoomFor(sds s, size_t addlen);
void sdsIncrLen(sds s, int incr);
//清除free记录长度的串
sds sdsRemoveFreeSpace(sds s);
//返回sds的真是长度,包括头部,字符串内容,尾部的0
size_t sdsAllocSize(sds s);
具体的内容下一篇再介绍。
Redis自定义动态字符串(sds)模块(一)的更多相关文章
- Redis自定义动态字符串(sds)模块(二)
sds模块的具体实现: 1.sdsnewlen 根据参数生成一个sds字符串 sds sdsnewlen(const void *init, size_t initlen) { struct sdsh ...
- redis 5.0.7 源码阅读——动态字符串sds
redis中动态字符串sds相关的文件为:sds.h与sds.c 一.数据结构 redis中定义了自己的数据类型"sds",用于描述 char*,与一些数据结构 typedef c ...
- Redis底层探秘(一):简单动态字符串(SDS)
redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...
- 图解Redis之数据结构篇——简单动态字符串SDS
图解Redis之数据结构篇--简单动态字符串SDS 前言 相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...
- Redis—简单动态字符串(SDS)
目录 Redis-简单动态字符串(SDS) SDS的定义 SDS与C字符串的区别 1. 常数复杂度获取字符串长度: 2. 杜绝缓冲区溢出: 3. 减少修改字符串时带来的内存重分配次数 4. 二进制安全 ...
- Redis数据结构之简单动态字符串SDS
Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...
- redis 系列3 数据结构之简单动态字符串 SDS
一. SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...
- Redis源码解析:01简单动态字符串SDS
Redis没有直接使用C字符串(以'\0'结尾的字符数组),而是构建了一种名为简单动态字符串( simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默认字符 ...
- Redis源码阅读笔记(1)——简单动态字符串sds实现原理
首先,sds即simple dynamic string,redis实现这个的时候使用了一个技巧,并且C99将其收录为标准,即柔性数组成员(flexible array member),参考资料见这里 ...
随机推荐
- webrtc第二篇 聊天室
聊天室模型不一样考虑的问题也不一样 1.websocket文本聊天 * step1 : 向聊天室所有用户(不包括该用户自己)发送当前用户上线信息.客户端用户栏回添加此用户 * step2 : 将该用户 ...
- [原创]svn 常见错误总结
错误: Unable to make name in 'X:\nfs\drivers\can_uart\.svn\tmp' 解决: 改变当前文件夹的权限 linux 下显示修改的文件名 参考链接:ht ...
- windows 下wamp环境1 配置之apache的安装
一.安装apache2.4 打开网站 apachelounge.com https://www.apachelounge.com/ 点击左侧Downloads,然后选择对应的版本,这里选择Apa ...
- H53D旋转-遁地龙卷风
(-1)写在前面 首先图片是我从互联网上下载的,向这位前辈致敬.我用的是chrome49,没有加不同浏览器的前缀,jquery3.0,图片资源放在了我的百度云盘上http://pan.baidu.co ...
- webpack 教程 那些事儿04-webpack项目实战分析
这节主要讲解真正项目用用到的 webpack配置问题,项目实战篇 就像我们不会完全做一个项目,不用别人的轮子一样.这个配置我们借用 vue-cli 搭建的配置来研究,因为它已经足够优秀. 有了前面的基 ...
- Codeforces Round #288 (Div. 2) E. Arthur and Brackets
题目链接:http://codeforces.com/contest/508/problem/E 输入一个n,表示有这么多对括号,然后有n行,每行输入一个区间,第i行的区间表示从前往后第i对括号的左括 ...
- 剑指Offer 旋转数组的最小数字
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转 ...
- Configuration
package edu.fzu.ir.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNot ...
- 【Supervisor】使用 Supervisor source command not found 如何解决
结论: The source command is only available in bash, and the supervisor command is run by sh. I would r ...
- Angularjs与bootstrap.datetimepicker结合实现日期选择器
http://www.lovelucy.info/angularjs-best-practices.html http://damoqiongqiu.iteye.com/blog/1917971 ht ...