redis 字符串

字符串

typedef char *sds;

struct sdshdr {
	unsigned int len;		//記錄已經使用字節數
	unsigned int free;		//記錄未使用字節數
	char buf[];				//字節數組
};

sds組織如下:

下面基於sdshdr 結構,分析下一些sds api 調用:

//新分配一個sds結構,同時buf指向的地址是連續的
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);	//cpy
    sh->buf[initlen] = '\0';				//設置最後一個字節爲’\0’
    return (char*)sh->buf;
}
sdsempty、sdsnew、sdsdup都是基於sdsnewlen
//更新長度
void sdsupdatelen(sds s) {
    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));	//獲取頭部
    int reallen = strlen(s);								//獲取長度
    sh->free += (sh->len-reallen);						//更新free
    sh->len = reallen;									//更新len
}
//申請空間,如果free 還足夠,直接返回,如果不夠,新申請
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;
    len = sdslen(s);
    sh = (void*) (s-(sizeof(struct sdshdr)));
newlen = (len+addlen);
//新申請空間小於1M,以新長度的2倍爲增長,超過1M,每次增長1M
    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;
}
//刪除free空間
sds sdsRemoveFreeSpace(sds s) {
    struct sdshdr *sh;

    sh = (void*) (s-(sizeof(struct sdshdr)));
    sh = zrealloc(sh, sizeof(struct sdshdr)+sh->len+1);
    sh->free = 0;
    return sh->buf;
}

 

發佈了83 篇原創文章 · 獲贊 8 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章