码迷,mamicode.com
首页 > 其他好文 > 详细

处理字符串时如何选择buffer的大小和分配方式 - 看看 redis 是怎么做的

时间:2015-05-16 21:53:25      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:字符串处理   redis   

最近在阅读 redis 代码, 觉得 如何阅读 Redis 源码 提供了的阅读顺序还不错, 因为之前有读过 lua 代码, 也有一点经验, 感觉作者建议的顺序还是比较合理的. 所以先从 redis 的内部字符串的实现开始看起, 在阅读过程中看到一个我个人认为很赞的技巧. 先贴代码:

(不得不说, redis 的代码注释真是详尽到了极致 … lua的注释很本没法比啊)

sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
    va_list cpy;
    char staticbuf[1024], *buf = staticbuf, *t;
    size_t buflen = strlen(fmt)*2;

    /* We try to start using a static buffer for speed.
     * If not possible we revert to heap allocation. */
    if (buflen > sizeof(staticbuf)) {
        buf = zmalloc(buflen);
        if (buf == NULL) return NULL;
    } else {
        buflen = sizeof(staticbuf);
    }

    /* Try with buffers two times bigger every time we fail to
     * fit the string in the current buffer size. */
    while(1) {
        buf[buflen-2] = ‘\0‘;
        va_copy(cpy,ap);
        vsnprintf(buf, buflen, fmt, cpy);
        va_end(cpy);
        if (buf[buflen-2] != ‘\0‘) {
            if (buf != staticbuf) zfree(buf);
            buflen *= 2;
            buf = zmalloc(buflen);
            if (buf == NULL) return NULL;
            continue;
        }
        break;
    }

    /* Finally concat the obtained string to the SDS string and return it. */
    t = sdscat(s, buf);
    if (buf != staticbuf) zfree(buf);
    return t;
}

sds 是 redis 的内部字符串类型, 其实就是 char * 的 typedef, 区别在其存取方式上, 这里把它当成 char * 就可以了.

几乎从函数名我们就能知道这个函数功能是将 字符串 s 和 格式化后的字符串 拼接在一起, 并返回这个新的字符串.

要实现这个功能不难, 但有一个问题需要考虑, 因为 ‘格式化的字符串’ 的长度你是不知道的, 所以我们需要用到 buffer, 但 buffer 应该选多大, 是直接放在函数栈上还是放在堆上? 这是个问题.

redis 采用的办法是:

  1. 先在栈上开一个 1024 字节 staticbuf 数组;
  2. 估计一下可能的 ‘格式化字符串’ 的大小 ( strlen(fmt) *2 );
  3. 如果 ‘格式化字符串’ 长度大于 staticbuf 数组长度, 那么就用 zmalloc (可以看作 malloc) 在堆上开一块相应大小的内存;
  4. 如果实际的 ‘格式化字符串’ 比估计大怎么办? 先 zfree (可以看作 free) 之前在堆上开的内存, 然后再在堆上开一块 2倍于之前大小的内存;
  5. 如果还是不够, 重复 4;
  6. 最后记得释放堆内存 (如果开辟了的话), 防止内存泄露.

处理字符串时如何选择buffer的大小和分配方式 - 看看 redis 是怎么做的

标签:字符串处理   redis   

原文地址:http://blog.csdn.net/xzz_hust/article/details/45771347

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!