字符串
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;
}