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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值