您的位置:首页 > 数据库 > Redis

redis源码分析-1 字符串处理

2014-01-25 19:57 357 查看
redis是一个键值对的数据库,说道key/value,很大程度就涉及到字符串的处理,redis是用c语言开发的,c语言自带的字符串进行字符串拓容,剪断,查看字符串长度等方面的时间复杂度均为n,这对一个经常要修改长度的字符串来说是一件很恐怖的事情,一个很简单的操作需要耗费的时间有点儿多了,这儿redis做了自己的优化。redis存储字符串用的是一个这样的结构

<!-- lang: cpp -->
struct sdshdr {
int len;//buf已占用长度
int free;//buf剩余可用长度
char buf[];    //实际上保留字符串的地方
};

<!-- lang: cpp -->

sds sdsMakeRoomFor(
sds s,
size_t addlen   // 需要增加的空间长度
)
{
struct sdshdr *sh, *newsh;
size_t free = sdsavail(s);
size_t len, newlen;

// 剩余空间可以满足需求,无须扩展
if (free >= addlen) return s;

sh = (void*) (s-(sizeof(struct sdshdr)));

// 目前 buf 长度
len = sdslen(s);
// 新 buf 长度
newlen = (len+addlen);
// 如果新 buf 长度小于 SDS_MAX_PREALLOC 长度
// 那么将 buf 的长度设为新 buf 长度的两倍
if (newlen < SDS_MAX_PREALLOC)
newlen *= 2;
else
newlen += SDS_MAX_PREALLOC;

// 扩展长度
newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);

if (newsh == NULL) return NULL;

newsh->free = newlen - len;

return newsh->buf;
}

默认初始化的时候len = 0, free = 0, buf为空,追加字符串的时候,首先判断添加的字符串的长度是否大于free,如果不大于free,就直接在buf里头填充。否则就要进行拓展,拓展的规则是,新的字符串的长度小于10241024的话,就将字符串分配2倍与所需的长度,否着分配新的长度+10241024,这就是redis在这个地方的优化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: