Search code examples
cpointersredisencapsulation

Why redis sds expose buf part to upper layer instead of whole sdshdr


When redis creates a sds (simple dynamic string), it inits whole sdshdr struct, then just returns buf part.

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

    if (sh == NULL) return NULL;

    sh->len = initlen;
    sh->free = 0;

    if (initlen && init)
        memcpy(sh->buf, init, initlen);
    sh->buf[initlen] = '\0';

    // just return buf part
    return (char*)sh->buf;
}

When redis needs to manipulate sds, it has to calculate the pointer to sdshdr struct. For exapmle, sdsclear function (lazy deletion of sds):

void sdsclear(sds s) {
    // calculate the pointer to sdshdr
    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));

    sh->free += sh->len;
    sh->len = 0;
    sh->buf[0] = '\0';
}

Is that for hiding sds inner structure from upper layer?


Solution

  • Exactly what @hobbs said - sds looks like a regular char buffer so you can use it with regular string functions (e.g. strcmp)