深入redis内部--实现字符串
redis字符串的定义和实现在Ssd.h和Ssd.c中。
1.定义
typedef char *sds; //本质是字符char的指针
2.字符串的操作
sds sdsnew(const char *init) {
size_t initlen = (init == NULL) ? 0 : strlen(init);
return sdsnewlen(init, initlen);
}
调用sdsnewlen,看一下该函数的实现
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
if (init) {
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
} else {
sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
}
if (sh == NULL) return NULL;
sh->len = initlen;
sh->free = 0;
if (initlen && init)
memcpy(sh->buf, init, initlen);
sh->buf[initlen] = '\0';
return (char*)sh->buf;
}
该函数使用redis自定义函数的zmalloc或者zcalloc分配内存(以后章节会专门深入这些函数)。
3.创建字符串使用了另一个结构(红色标注)
struct sdshdr {
int len;
int free;
char buf[];
};
从上面的函数可以得出创建字符串时,返回的是一个字符数组的指针。
该结构和字符串的关系如下:
static inline size_t sdslen(const sds s) {
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;
}
4. 操作字符串的方法
sds sdsnewlen(const void *init, size_t initlen); //实际真正创建字符串的函数,使用sdsnew创建字符串时该函数被调用。
sds sdsnew(const char *init); //创建字符串函数
sds sdsempty(void); //创建一个长度为0的空字符串
size_t sdslen(const sds s); //计算字符串的长度
sds sdsdup(const sds s); //复制字符串
void sdsfree(sds s); //从内存中释放字符串,调用zfree方法
size_t sdsavail(const sds s); //计算字符串的可用长度(字符数组中还没有使用的长度)
sds sdsgrowzero(sds s, size_t len); //增加字符串的内存,并使用'\0'填充
sds sdscatlen(sds s, const void *t, size_t len); //字符串拼接常量实现函数,使用sdscat时调用该函数
sds sdscat(sds s, const char *t); //字符串拼接常量函数
sds sdscatsds(sds s, const sds t); //字符串拼接字符串函数
sds sdscpylen(sds s, const char *t, size_t len); //字符串复制的执行函数
sds sdscpy(sds s, const char *t); //将字符串t复制到s中,若s空间不足,使用sdsgrowzero增加空间
sds sdscatvprintf(sds s, const char *fmt, va_list ap); //类似sdscatprintf,但参数不是变长的,是固定的
#ifdef __GNUC__ //如果是linux平台,使用GNU编译器
sds sdscatprintf(sds s, const char *fmt, ...)
__attribute__((format(printf, 2, 3))); //format (archetype, string-index, first-to-check) 告诉编译器,按照printf, scanf, strftime
//或strfmon的参数表格式规则对该函数的参数进行检查。“archetype”指定是哪种风格;
//“string-index”指定传 入函数的第几个参数是格式化字符串;“first-to-check”
//指定从函数的第几个参数开始按上述规则进行检查。
#else
sds sdscatprintf(sds s, const char *fmt, ...); //向参数s添加字符串,实例:s = sdscatprintf(s,"%d+%d = %d",a,b,a+b).
#endif
sds sdstrim(sds s, const char *cset); //从左边或者后边移除制定的字符串cset,
* Example:
* s = sdsnew("AA...AA.a.aa.aHelloWorld :::");
* s = sdstrim(s,"A. :");
* printf("%s\n", s);
* Output will be just "Hello World".
sds sdsrange(sds s, int start, int end); //从字符串s中截取制定索引位置的子字符串。
void sdsupdatelen(sds s); //更新字符串的长度。应用实例: 如果没有sdsupdatelen,则结果为2,有则结果为6
* s = sdsnew("foobar");
* s[2] = '\0';
* sdsupdatelen(s);
* printf("%d\n", sdslen(s));
void sdsclear(sds s); //将字符串的buf设置为'\0'
int sdscmp(const sds s1, const sds s2); //使用memcpy()比较两个字符串,如果s1>s2则结果为1,s1=s2则结果为0,s1<s2则为-1
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);//使用sep分隔符分割s,返回字符串数组
void sdsfreesplitres(sds *tokens, int count); //tokens为null时不执行任何操作,否则清空sdssplitlen()函数返回的结果。
void sdstolower(sds s); //将字符串的每个字符转换为小写形式
void sdstoupper(sds s); //将字符串的每个字符转换为大写形式
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);
/* Modify the string substituting all the occurrences of the set of
* characters specified in the 'from' string to the corresponding character in the 'to' array.
* For instance: sdsmapchars(mystring, "ho", "01", 2)
* will have the effect of turning the string "hello" into "0ell1".
sds sdsMakeRoomFor(sds s, size_t addlen);
* Enlarge the free space at the end of the sds string so that the caller
* is sure that after calling this function can overwrite up to addlen
* bytes after the end of the string, plus one more byte for nul term.
void sdsIncrLen(sds s, int incr); //根据incr来在字符串的尾部增加字符串长度或者减少剩余字符串空间
sds sdsRemoveFreeSpace(sds s); //当字符串没有剩余空间时,重新分配字符串。
size_t sdsAllocSize(sds s); //
深入redis内部--实现字符串的更多相关文章
- redisbook笔记——redis内部数据结构
在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 S ...
- 关于redis内部的数据结构
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- [转]Redis内部数据结构详解-sds
本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...
- redis内部数据结构深入浅出
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- PHP操作redis之String(字符串)、List(列表)(一)
Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key – value 缓存产品有以下三个特点: Redis支持数据的持久 ...
- redis内部数据结构
redis内部数据结构,是指redis在自身的构建中,基于这些特定的内部数据结构进行的. 简单动态字符串:Simple Dynamic String 双端链表 字典:Dictonary 跳跃表:ski ...
- Redis学习笔记-Redis内部数据结构
Redis内部数据结构 Redis和其他key-value数据库的很大区别是它支持非字符串类型的value值.它支持的value值的类型如下: sds (simple dynamic string) ...
- Redis实现之字符串
简单动态字符串 Redis中的字符串并不是传统的C语言字符串(即字符数组,以下简称C字符串),而是自己构建了一种简单动态字符串(simple dynamic string,SDS),并将SDS作为Re ...
- 探索Redis设计与实现4:Redis内部数据结构详解——ziplist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
随机推荐
- js如何给当前日期+1?
一天=24小时=1440分钟=86400秒 所以给当前日期加一天的步骤为: 1.获取当前日期: 2.利用86400秒给其进行加一天操作: 3.类似加一天,两天,一月,一年等,过程如此. 代码如下(以j ...
- java.lang.IllegalArgumentException: No converter found for return value of type: class com.smart.result.Page
今天学习了一下spring boot 中的mybatis,用mybatis来增删改查用户,获取用户,添加用户,修改用户,删除用户,修改用户,都是可以的,但是获取带分页的用户列表,一直抛出这个java. ...
- Media change : please insert the disk labeled
在Debian中使用apt-get安装软件包时经常会提示让你插入netinst的光盘: Media change: please insert the disc labeled 当没有时就无法进行安装 ...
- ClamAV学习【7】——病毒库文件格式学习
搜查到一份详细的ClamAV病毒文件格式资料(http://download.csdn.net/detail/betabin/4215909),英文版,国内这资料不多的感觉. 重点看了下有关PE的病毒 ...
- Java50道经典习题-程序17 猴子吃桃问题
题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个 第二天早上又将剩下的桃子吃掉一半,又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上想再吃时,见只 ...
- 十一、linux文件系统权限详解
对于文件系统权限,我们前面已经讲解了一部分,这里就不在重复了. 1.修改文件权限有两种,一种是数字.一种是字母 (chmod 的修改只能是属主或者root) 数字: 修改目录权限和目录内所有文件的权限 ...
- DESTOON从CSRF到GETSHELL
本文作者:薄荷糖微微凉 Destoon B2B网站管理系统是一套完善的B2B(电子商务)行业门户解决方案.系统基于PHP+MySQL开发,采用B/S架构,模板与程序分离,源码开放.模型化的开发思路,可 ...
- 分享一些JAVA常用的学习网站
常用学习网站freecodecamp 一个非常好的网站,教学模式类似游戏中的闯关,通过每关之后会有成就感,在该网站还有设有聊天室,可以进行相关的技术交流,很棒的学习网站. https://www.fr ...
- Tomcat启动和请求处理解析
tomcat是我们经常使用的组件,但是内部是如何运行的呢,我们去一探究竟. 1.tomcat架构 tomcat的整体架构图如下: Tomcat中只有一个Server,一个Server可以有多个Serv ...
- v-bind、v-on 的缩写
Vue中的缩写:v-bind.v-on v-bind 缩写:: 预期:any (with argument) | Object (without argument) 参数:attrOrProp (op ...