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),参考资料见这里 ...
随机推荐
- Ubuntu 14 修改默认打开方式
通过研究,有三种修改方式. 方式一: 修改路径:右上角“系统设置” -> 详细信息 -> 默认应用程序 但是,有个缺陷,可修改的项比较少. 方式二: 例如,修改pdf的打开方式,只要查看任 ...
- 安卓手机当Mac、Win和Linux外置WIFI网卡
Android手机都有USB共享网络的功能 ,利用此功能可以将网络共享给电脑 基本原理: 手机连接WIFI,开启USB网络共享,mac笔记本上网 (两款手机示意图) 博主实践证明: win10与Ubu ...
- BZOJ1483——[HNOI2009]梦幻布丁
1.题目大意:这题就是给你一个序列,有两个操作,一个是询问序列中的连续段数,比如序列 1 2 2 1就是三段.. 1是一段,2 2 又是一段,1又是一段,就是相同的在一起,第二个操作就是将其中的一种数 ...
- C++关键字:mutable(转)
参考:http://blog.csdn.net/hxz_qlh/article/details/14475573 修饰成员变量,在const成员函数中可修改它,在C++中还从未用过这个关键字.
- eclipse中整合springMvc,velocity和sitemesh
1.项目所需要jar包 (有些可能多余) 2.创建UserController 目录如下: package qust.thb.usermanage.controller; import org.s ...
- jQuery lazyload插件详解和问题解答
lazyload插件用于图片延迟加载,节省服务器带宽,减少服务器请求次数,提高网站的页面加载速度,用于网站性能优化,只有当图片在窗口可视范围内时才向服务器请求: 参数: threshold:设置距离窗 ...
- Java abstract
abstract修饰符可以修饰类和方法. (1)abstract修饰类,会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,也就是编译时类型.抽象类就相当于一类的半成品, ...
- 17.4---返回max,不用if
思路:借助max公式就可以了.max(x,y)=0.5*(x+y+|x-y|) 注意:1,结尾要加(int). 答案: max(x,y)=0.5*(x+y+|x-y|)
- phpcms模板标签整理
{template "content","header"} 调用根目录下phpcms\template\content\header文件 {CHARSET} 字 ...
- pycharm 中 pep8 检查开启.
pycharm pep8检查的开启,默认是暗黄色,我这里为了醒目给改成了黄色.