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;}

这里有用到zmalloczcalloc两个函数,具体分析不在赘述。zmallocmalloc的主要区别在于zmallocmalloc多分配了一定的空间(据平台而定),这个多余的空间用来存储zmalloc本要分配的大小。zcalloczmalloc的区别在于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';}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 珠海人力资源网 人力资源和社会保障局 珠海人力资源 四川人力社会保障网 人力资源保障 山东省人力资源和社会保障厅 重庆人力资源和社会保障网 人力资源保障局 四川人力资源和社会保障厅 重庆人力资源网 人力资源模块 甘肃省人力资源和社会保障厅 甘肃省人力资源社会保障厅 山东省人力资源社会保障厅 人力资源大模块 人力资源社会保障部 四川省人力和社会保障厅 淄博市人力资源和社会保障网 甘肃人力资源社会保障厅 重庆人力和社会保障网 淄博市人力资源社会保障网 山东省人力资源保障厅 贵阳人力资源网 重庆人力社会保障网 重庆人力资源 广州市人力资源社会保障局 甘肃人力资源保障厅 广州市人力资源和社会保障局 人力社会保障局社保网 深圳市人力资源社会保障局 贵阳人力资源 深圳市人力资源和社会保障局 重庆市人力资源和社会保障局 青岛市人力资源和社会保障局 罗德岛人力资源部 河南省人力资源和社会保障厅 重庆人力资源和社保局网 潍坊市人力资源和社会保障局 台山人才人力资源网 河南省人力资源社会保障厅 重庆市人力资源社会保障局