redis源码分析(2)——SDS API详解
来源:互联网 发布:自动对比度算法 编辑:程序博客网 时间:2024/06/03 15:46
源码分析章节,我尽量使用原生的redis源码,不去看黄建宏的注释,提高自己阅读源码的能力,此外,redis版本还是3.0
源码下载,大家可以到这 http://download.redis.io/releases/
sdsnew
typedef char *sds;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); } //分配失败返回NULL if (sh == NULL) return NULL; sh->len = initlen; sh->free = 0;//这里可以看到sds初始是不会分配多余空间的。 if (initlen && init) //如果init中原来有内容则拷贝。 memcpy(sh->buf, init, initlen); sh->buf[initlen] = '\0'; return (char*)sh->buf;}
这里有用到zmalloc
和zcalloc
两个函数,具体分析不在赘述。zmalloc
和malloc
的主要区别在于zmalloc
比malloc
多分配了一定的空间(据平台而定),这个多余的空间用来存储zmalloc
本要分配的大小。zcalloc
与zmalloc
的区别在于zmalloc
不会初始化内存,而zcalloc
会初始化。
sdsempty
创建并返回一个只保存了空字符串 ""
的 sds。
sds sdsempty(void) {
return sdsnewlen(“”,0);
}
sdsnew
把一个给定的c字符串转为sds。
sds sdsnew(const char *init) { size_t initlen = (init == NULL) ? 0 : strlen(init); return sdsnewlen(init, initlen);}
sdsdup
拷贝sds
sds sdsdup(const sds s) { return sdsnewlen(s, sdslen(s));}
sdsfree
释放sds
void sdsfree(sds s) { if (s == NULL) return; zfree(s-sizeof(struct sdshdr));}
zfree
的功能
释放内存并修改redis使用的内存大小。
sdsupdatelen
?废弃函数
根据代码我猜测是重新设置sds的大小
eg.
sds={10,0,"abc"/"abc\0defghi"}==>sds={3,7,"abc"}
void sdsupdatelen(sds s) { struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr))); int reallen = strlen(s); sh->free += (sh->len-reallen); sh->len = reallen;}
sdsclear
在不去真实释放sds空间的情况下,将sds变为空字符串。
void sdsclear(sds s) { // 取出 sdshdr struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr))); sh->free += sh->len; sh->len = 0; sh->buf[0] = '\0';}
sdsMakeRoomFor
sdsRemoveFreeSpace
真正的释放了惰性空间释放时的多余空间
sds sdsRemoveFreeSpace(sds s) { struct sdshdr *sh; sh = (void*) (s-(sizeof(struct sdshdr))); // 进行内存重分配,让 buf 的长度仅仅足够保存字符串内容 // T = O(N) sh = zrealloc(sh, sizeof(struct sdshdr)+sh->len+1); // 空余空间为 0 sh->free = 0; return sh->buf;}
sdsAllocSize
获得sds一共分配保存字符串的空间(len+free+'\0'
)
size_t sdsAllocSize(sds s) { struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr))); return sizeof(*sh)+sh->len+sh->free+1;}
sdsIncrLen
void sdsIncrLen(sds s, int incr) { struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr))); // 确保 sds 空间足够 assert(sh->free >= incr); // 更新属性 sh->len += incr; sh->free -= incr; // 这个 assert 其实可以忽略 // 因为前一个 assert 已经确保 sh->free - incr >= 0 了 assert(sh->free >= 0); // 放置新的结尾符号 s[sh->len] = '\0';}
阅读全文
0 0
- redis源码分析(2)——SDS API详解
- Redis源码分析——SDS
- Redis源码分析(一)——Redis数据结构-字符串SDS
- redis源码分析-sds字符串
- Redis源码分析(sds)
- Redis源码阅读笔记—sds
- Redis源码分析(五)——简单动态字符串(sds)
- 【redis源码分析】动态字符串--sds
- redis源码分析(3)sds
- Redis源码分析(四)-- sds字符串
- Redis源码学习1——基本数据结构sds
- Redis源码学习1——基本数据结构sds
- Redis源码学习1——基本数据结构sds
- redis源码分析笔记2- redis的数据类型-动态字符串sds
- redis 源码笔记--sds
- Redis源码解析【SDS】
- redis分析-SDS
- redis-SDS 分析
- 机器学习笔记之(三)常用的求导公式
- hdu 1233 还是畅通工程 最小生成树
- Python作用域总结
- tcp 服务端如何判断客户端断开连接
- python tkinter grid 拉伸
- redis源码分析(2)——SDS API详解
- redis Lua脚本(二)
- 一口气搞懂《虚函数和纯虚函数》
- Python基础 itertools
- Rxjava+Retrofit+Okhttp(原理)
- 低价购买
- RDD
- 上传csv格式文件,利用commons-fileupload
- hadoop运行环境的搭建