新增sds.c sds.h zmalloc.c部分注释
This commit is contained in:
parent
37273e0dd8
commit
1b901cf01a
325
src/sds.c
325
src/sds.c
@ -63,7 +63,7 @@ static inline int sdsHdrSize(char type) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* 通过sds字符串长度获取sds类型
|
||||
* 通过sds字符串长度获取所需要的sds类型
|
||||
* @param string_size 字符串长度
|
||||
* @return 字符串类型
|
||||
*/
|
||||
@ -213,7 +213,7 @@ sds _sdsnewlen(const void *init, size_t initlen, int trymalloc) {
|
||||
return s;
|
||||
}
|
||||
/**
|
||||
* 创建sds字符串
|
||||
* 创建sds字符串 使用s_malloc_usable创建内存空间
|
||||
* @param init 任意类型的值 常量 值不可更改 但指针可以更改指向的对象
|
||||
* @param initlen
|
||||
* @return 字符串
|
||||
@ -222,7 +222,7 @@ sds sdsnewlen(const void *init, size_t initlen) {
|
||||
return _sdsnewlen(init, initlen, 0);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* 尝试创建sds,使用s_trymalloc_usable创建内存空间
|
||||
* @param init 任意类型的值
|
||||
* @param initlen
|
||||
* @return
|
||||
@ -230,27 +230,44 @@ sds sdsnewlen(const void *init, size_t initlen) {
|
||||
sds sdstrynewlen(const void *init, size_t initlen) {
|
||||
return _sdsnewlen(init, initlen, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建0长度的字符串
|
||||
* @return sds字符串
|
||||
*/
|
||||
/* Create an empty (zero length) sds string. Even in this case the string
|
||||
* always has an implicit null term. */
|
||||
sds sdsempty(void) {
|
||||
return sdsnewlen("",0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从一个以null结尾的 C字符串 创建一个新的sds字符串
|
||||
* @param init
|
||||
* @return
|
||||
*/
|
||||
/* Create a new sds string starting from a null terminated C string. */
|
||||
sds sdsnew(const char *init) {
|
||||
// 判断传入的字符串是否为NULL 如果为NULL为创建一个空的sds字符串,否则创建strlen(init)长度的sds字符串
|
||||
size_t initlen = (init == NULL) ? 0 : strlen(init);
|
||||
return sdsnewlen(init, initlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制一个sds
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
/* Duplicate an sds string. */
|
||||
sds sdsdup(const sds s) {
|
||||
return sdsnewlen(s, sdslen(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放sds字符串
|
||||
* @param s sds字符串
|
||||
*/
|
||||
/* Free an sds string. No operation is performed if 's' is NULL. */
|
||||
void sdsfree(sds s) {
|
||||
//如果sds字符串为NULL为不作操作
|
||||
if (s == NULL) return;
|
||||
//释放内存空间
|
||||
s_free((char*)s-sdsHdrSize(s[-1]));
|
||||
}
|
||||
|
||||
@ -268,8 +285,24 @@ void sdsfree(sds s) {
|
||||
* The output will be "2", but if we comment out the call to sdsupdatelen()
|
||||
* the output will be "6" as the string was modified but the logical length
|
||||
* remains 6 bytes. */
|
||||
/**
|
||||
* 将sds的已经使用的长度修改成第一个'\0'结尾的字符串的长度,相当于从第一个\0截断
|
||||
*
|
||||
* 当修改给sds字符串中某一个字符为'\0' ,
|
||||
* 此时需要执行该方法去更新sds字符串长度,因为sds长度记录在sds头len中,如果不去更新,则sds长度不变,
|
||||
* 例子:
|
||||
* s = sdsnew("foobar");
|
||||
* s[2] = '\0';
|
||||
* dsupdatelen(s);
|
||||
* rintf("%d\n", sdslen(s));
|
||||
* 此时输出长度为2
|
||||
* 如果没有dsupdatelen(s); 则sds长度还是原来的6
|
||||
* @param s
|
||||
*/
|
||||
void sdsupdatelen(sds s) {
|
||||
//获取sds长度即 到第一个'\0'的长度
|
||||
size_t reallen = strlen(s);
|
||||
// 给sds设置新的长度
|
||||
sdssetlen(s, reallen);
|
||||
}
|
||||
|
||||
@ -277,6 +310,11 @@ void sdsupdatelen(sds s) {
|
||||
* However all the existing buffer is not discarded but set as free space
|
||||
* so that next append operations will not require allocations up to the
|
||||
* number of bytes previously available. */
|
||||
/**
|
||||
* 将sds的内存清零但不释放
|
||||
* 设置sds长度为0,并将第一个字符位置设置为结束符 '\0'
|
||||
* @param s
|
||||
*/
|
||||
void sdsclear(sds s) {
|
||||
sdssetlen(s, 0);
|
||||
s[0] = '\0';
|
||||
@ -288,53 +326,79 @@ void sdsclear(sds s) {
|
||||
*
|
||||
* Note: this does not change the *length* of the sds string as returned
|
||||
* by sdslen(), but only the free buffer space we have. */
|
||||
/**
|
||||
* 给一个sds扩充空间以供以后使用
|
||||
* 该方法用于添加sds字符串sds的alloc的小 即可用空间大小,不会改变字符串长度
|
||||
* @param s sds字符串
|
||||
* @param addlen 需要新增的大小
|
||||
* @return sds字符串
|
||||
*/
|
||||
sds sdsMakeRoomFor(sds s, size_t addlen) {
|
||||
void *sh, *newsh;
|
||||
//获取sds当前可用空间
|
||||
size_t avail = sdsavail(s);
|
||||
size_t len, newlen, reqlen;
|
||||
//获取sds的类型 s[-1]= flags oldtype = flags & SDS_TYPE_MASK;
|
||||
char type, oldtype = s[-1] & SDS_TYPE_MASK;
|
||||
int hdrlen;
|
||||
size_t usable;
|
||||
|
||||
//如果可用空间大于扩容大小 则无须扩容直接返回
|
||||
/* Return ASAP if there is enough space left. */
|
||||
if (avail >= addlen) return s;
|
||||
|
||||
//判断字符串长度
|
||||
len = sdslen(s);
|
||||
//获取sds类型结构占用的内存大小
|
||||
sh = (char*)s-sdsHdrSize(oldtype);
|
||||
//新的内存大小等于 sds字符串长度+新增长度
|
||||
reqlen = newlen = (len+addlen);
|
||||
//断言 新增后的长度要大于 sds字符串长度
|
||||
assert(newlen > len); /* Catch size_t overflow */
|
||||
//如果新的长度小于 1M,则扩容为其2倍
|
||||
if (newlen < SDS_MAX_PREALLOC)
|
||||
newlen *= 2;
|
||||
//否则+1M
|
||||
else
|
||||
newlen += SDS_MAX_PREALLOC;
|
||||
|
||||
//修改要扩容sds字符串的类型
|
||||
type = sdsReqType(newlen);
|
||||
|
||||
/* Don't use type 5: the user is appending to the string and type 5 is
|
||||
* not able to remember empty space, so sdsMakeRoomFor() must be called
|
||||
* at every appending operation. */
|
||||
//如果类型是SDS_TYPE_5 的话将类型设置为 SDS_TYPE_8
|
||||
if (type == SDS_TYPE_5) type = SDS_TYPE_8;
|
||||
|
||||
//获取新的类型的结构占用的空间大小
|
||||
hdrlen = sdsHdrSize(type);
|
||||
//断言 新的类型结构占用的空间 + 扩容后的长度+1 要大于 扩容前sds字符串长度+addlen新增长度
|
||||
assert(hdrlen + newlen + 1 > reqlen); /* Catch size_t overflow */
|
||||
if (oldtype==type) {
|
||||
//如果旧的类型和新的类型一致,则重新分配内存
|
||||
newsh = s_realloc_usable(sh, hdrlen+newlen+1, &usable);
|
||||
if (newsh == NULL) return NULL;
|
||||
s = (char*)newsh+hdrlen;
|
||||
} else {
|
||||
/* Since the header size changes, need to move the string forward,
|
||||
* and can't use realloc */
|
||||
//如果新类型和旧内存不一致则重新创建一个新的内存空间
|
||||
//分配内存 如果为NULL则内存分配失败 否则usable为可用内存大小
|
||||
newsh = s_malloc_usable(hdrlen+newlen+1, &usable);
|
||||
if (newsh == NULL) return NULL;
|
||||
//复制字符串
|
||||
memcpy((char*)newsh+hdrlen, s, len+1);
|
||||
//释放之前的sds字符串
|
||||
s_free(sh);
|
||||
s = (char*)newsh+hdrlen;
|
||||
//设置新标识
|
||||
s[-1] = type;
|
||||
//给sds设置新的长度
|
||||
sdssetlen(s, len);
|
||||
}
|
||||
//可用内存 = 分配的可用内存-sds类型结构内存-1
|
||||
usable = usable-hdrlen-1;
|
||||
//如果可用内存 > 类型最大的内存则重新设置sds类型
|
||||
if (usable > sdsTypeMaxSize(type))
|
||||
usable = sdsTypeMaxSize(type);
|
||||
//设置字符串可用内存为新分配的内存
|
||||
sdssetalloc(s, usable);
|
||||
return s;
|
||||
}
|
||||
@ -345,20 +409,32 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
||||
*
|
||||
* After the call, the passed sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
/**
|
||||
* 根据实际使用长度减少sds的分配内存 设置sds可用空间为0
|
||||
* 重新分配sds字符串内存空间,传入的s字符串将不可以,指针将指向新创建的sds字符串
|
||||
* @param s sds字符串
|
||||
* @return
|
||||
*/
|
||||
sds sdsRemoveFreeSpace(sds s) {
|
||||
void *sh, *newsh;
|
||||
//s[-1] = flags sds类型
|
||||
char type, oldtype = s[-1] & SDS_TYPE_MASK;
|
||||
int hdrlen, oldhdrlen = sdsHdrSize(oldtype);
|
||||
//获取sds字符串长度
|
||||
size_t len = sdslen(s);
|
||||
//获取s的可用内存
|
||||
size_t avail = sdsavail(s);
|
||||
//sda的buf长度 = sds长度 - sds类型结构占用的内存空间大小
|
||||
sh = (char*)s-oldhdrlen;
|
||||
|
||||
//如果可用空间已经为0,那么无须调整
|
||||
/* Return ASAP if there is no space left. */
|
||||
if (avail == 0) return s;
|
||||
|
||||
/* Check what would be the minimum SDS header that is just good enough to
|
||||
* fit this string. */
|
||||
//获取该长度所需要的的sds类型
|
||||
type = sdsReqType(len);
|
||||
//获取sds类型结构占用的内存大小
|
||||
hdrlen = sdsHdrSize(type);
|
||||
|
||||
/* If the type is the same, or at least a large enough type is still
|
||||
@ -366,18 +442,29 @@ sds sdsRemoveFreeSpace(sds s) {
|
||||
* only if really needed. Otherwise if the change is huge, we manually
|
||||
* reallocate the string to use the different header type. */
|
||||
if (oldtype==type || type > SDS_TYPE_8) {
|
||||
//如果旧sds类型和 sds字符串最少需要的sds类型一致,重新分配内存并将之前sds内存释放
|
||||
newsh = s_realloc(sh, oldhdrlen+len+1);
|
||||
//如果分配失败则返回NULL
|
||||
if (newsh == NULL) return NULL;
|
||||
//c 字符串
|
||||
s = (char*)newsh+oldhdrlen;
|
||||
} else {
|
||||
//sds字符串最少需要空间的sds类型 和 原sds类型不一致 分配内存
|
||||
newsh = s_malloc(hdrlen+len+1);
|
||||
//如果为NULL则分配失败
|
||||
if (newsh == NULL) return NULL;
|
||||
//复制
|
||||
memcpy((char*)newsh+hdrlen, s, len+1);
|
||||
//释放原sds串内存
|
||||
s_free(sh);
|
||||
// c串
|
||||
s = (char*)newsh+hdrlen;
|
||||
//设置新的类型
|
||||
s[-1] = type;
|
||||
//设置新的sds长度
|
||||
sdssetlen(s, len);
|
||||
}
|
||||
//设置sds可用内存为0的内存
|
||||
sdssetalloc(s, len);
|
||||
return s;
|
||||
}
|
||||
@ -389,13 +476,21 @@ sds sdsRemoveFreeSpace(sds s) {
|
||||
* 3) The free buffer at the end if any.
|
||||
* 4) The implicit null term.
|
||||
*/
|
||||
// 返回一个sds的总长度,包括头,二进制字符串分配的内存长度和'\0'
|
||||
size_t sdsAllocSize(sds s) {
|
||||
//sds分配的内存大小
|
||||
size_t alloc = sdsalloc(s);
|
||||
// sds类型结构占用的内存大小 + 可用内存空间 + 1
|
||||
return sdsHdrSize(s[-1])+alloc+1;
|
||||
}
|
||||
|
||||
/* Return the pointer of the actual SDS allocation (normally SDS strings
|
||||
* are referenced by the start of the string buffer). */
|
||||
/**
|
||||
* 返回一个sds的控制结构的起始地址
|
||||
* @param s sds字符串
|
||||
* @return
|
||||
*/
|
||||
void *sdsAllocPtr(sds s) {
|
||||
return (void*) (s-sdsHdrSize(s[-1]));
|
||||
}
|
||||
@ -423,6 +518,11 @@ void *sdsAllocPtr(sds s) {
|
||||
* ... check for nread <= 0 and handle it ...
|
||||
* sdsIncrLen(s, nread);
|
||||
*/
|
||||
/**
|
||||
* 增加一个sds的已经使用的长度,要求加完之后不能超过分配的内存长度
|
||||
* @param s
|
||||
* @param incr
|
||||
*/
|
||||
void sdsIncrLen(sds s, ssize_t incr) {
|
||||
unsigned char flags = s[-1];
|
||||
size_t len;
|
||||
@ -469,6 +569,12 @@ void sdsIncrLen(sds s, ssize_t incr) {
|
||||
*
|
||||
* if the specified length is smaller than the current length, no operation
|
||||
* is performed. */
|
||||
/**
|
||||
* 给一个sds的已经使用长度增加到指定长度,并将增加部分内存清零
|
||||
* @param s
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
sds sdsgrowzero(sds s, size_t len) {
|
||||
size_t curlen = sdslen(s);
|
||||
|
||||
@ -487,6 +593,13 @@ sds sdsgrowzero(sds s, size_t len) {
|
||||
*
|
||||
* After the call, the passed sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
/**
|
||||
* 在一个sds后面连接给定长度的二进制字符串
|
||||
* @param s
|
||||
* @param t
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
sds sdscatlen(sds s, const void *t, size_t len) {
|
||||
size_t curlen = sdslen(s);
|
||||
|
||||
@ -502,6 +615,12 @@ sds sdscatlen(sds s, const void *t, size_t len) {
|
||||
*
|
||||
* After the call, the passed sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
/**
|
||||
* 在一个sds后面连接一个C字符串
|
||||
* @param s
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
sds sdscat(sds s, const char *t) {
|
||||
return sdscatlen(s, t, strlen(t));
|
||||
}
|
||||
@ -510,12 +629,25 @@ sds sdscat(sds s, const char *t) {
|
||||
*
|
||||
* After the call, the modified sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
/**
|
||||
* 将一个sds的已经使用的内存连接到另一个sds中
|
||||
* @param s
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
sds sdscatsds(sds s, const sds t) {
|
||||
return sdscatlen(s, t, sdslen(t));
|
||||
}
|
||||
|
||||
/* Destructively modify the sds string 's' to hold the specified binary
|
||||
* safe string pointed by 't' of length 'len' bytes. */
|
||||
/**
|
||||
* 将一个给定长度的二进制字符串复制到sds,并更新已经使用的长度
|
||||
* @param s
|
||||
* @param t
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
sds sdscpylen(sds s, const char *t, size_t len) {
|
||||
if (sdsalloc(s) < len) {
|
||||
s = sdsMakeRoomFor(s,len-sdslen(s));
|
||||
@ -529,6 +661,12 @@ sds sdscpylen(sds s, const char *t, size_t len) {
|
||||
|
||||
/* Like sdscpylen() but 't' must be a null-termined string so that the length
|
||||
* of the string is obtained with strlen(). */
|
||||
/**
|
||||
* 将一个C字符串复制到sds
|
||||
* @param s
|
||||
* @param t
|
||||
* @return
|
||||
*/
|
||||
sds sdscpy(sds s, const char *t) {
|
||||
return sdscpylen(s, t, strlen(t));
|
||||
}
|
||||
@ -539,6 +677,9 @@ sds sdscpy(sds s, const char *t) {
|
||||
*
|
||||
* The function returns the length of the null-terminated string
|
||||
* representation stored at 's'. */
|
||||
/**
|
||||
* 将一个long long转换成C字符串格式
|
||||
*/
|
||||
#define SDS_LLSTR_SIZE 21
|
||||
int sdsll2str(char *s, long long value) {
|
||||
char *p, aux;
|
||||
@ -570,7 +711,12 @@ int sdsll2str(char *s, long long value) {
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个unsigned long long 转换成C字符串格式
|
||||
* @param s
|
||||
* @param v
|
||||
* @return
|
||||
*/
|
||||
/* Identical sdsll2str(), but for unsigned long long type. */
|
||||
int sdsull2str(char *s, unsigned long long v) {
|
||||
char *p, aux;
|
||||
@ -604,13 +750,24 @@ int sdsull2str(char *s, unsigned long long v) {
|
||||
*
|
||||
* sdscatprintf(sdsempty(),"%lld\n", value);
|
||||
*/
|
||||
/**
|
||||
* 使用long long制造一个sds
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
sds sdsfromlonglong(long long value) {
|
||||
char buf[SDS_LLSTR_SIZE];
|
||||
int len = sdsll2str(buf,value);
|
||||
|
||||
return sdsnewlen(buf,len);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将可变长格式化字符串连接到sds后面
|
||||
* @param s
|
||||
* @param fmt
|
||||
* @param ap
|
||||
* @return
|
||||
*/
|
||||
/* Like sdscatprintf() but gets va_list instead of being variadic. */
|
||||
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
|
||||
va_list cpy;
|
||||
@ -669,6 +826,13 @@ sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
|
||||
*
|
||||
* s = sdscatprintf(sdsempty(), "... your format ...", args);
|
||||
*/
|
||||
/**
|
||||
* 是sdscatvprintf的包装
|
||||
* @param s
|
||||
* @param fmt
|
||||
* @param ...
|
||||
* @return
|
||||
*/
|
||||
sds sdscatprintf(sds s, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
char *t;
|
||||
@ -694,6 +858,13 @@ sds sdscatprintf(sds s, const char *fmt, ...) {
|
||||
* %U - 64 bit unsigned integer (unsigned long long, uint64_t)
|
||||
* %% - Verbatim "%" character.
|
||||
*/
|
||||
/**
|
||||
* 和sdscatvprintf功能一样,区别是不使用sprintf族函数,性能高
|
||||
* @param s
|
||||
* @param fmt
|
||||
* @param ...
|
||||
* @return
|
||||
*/
|
||||
sds sdscatfmt(sds s, char const *fmt, ...) {
|
||||
size_t initlen = sdslen(s);
|
||||
const char *f = fmt;
|
||||
@ -802,6 +973,12 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
|
||||
*
|
||||
* Output will be just "HelloWorld".
|
||||
*/
|
||||
/**
|
||||
* 从sds的头和尾去掉所有和给定字符一致的内容,保留剩下的部分
|
||||
* @param s
|
||||
* @param cset
|
||||
* @return
|
||||
*/
|
||||
sds sdstrim(sds s, const char *cset) {
|
||||
char *start, *end, *sp, *ep;
|
||||
size_t len;
|
||||
@ -820,15 +997,25 @@ sds sdstrim(sds s, const char *cset) {
|
||||
/* Changes the input string to be a subset of the original.
|
||||
* It does not release the free space in the string, so a call to
|
||||
* sdsRemoveFreeSpace may be wise after. */
|
||||
/**
|
||||
*
|
||||
* @param s
|
||||
* @param start
|
||||
* @param len
|
||||
*/
|
||||
void sdssubstr(sds s, size_t start, size_t len) {
|
||||
/* Clamp out of range input */
|
||||
//获取sds长度
|
||||
size_t oldlen = sdslen(s);
|
||||
//如果起始点大于sds长度 则设置start = len = 0
|
||||
if (start >= oldlen) start = len = 0;
|
||||
//长度如果大于 sds长度-起始点 重新设置长度为 sds长度-起始点
|
||||
if (len > oldlen-start) len = oldlen-start;
|
||||
|
||||
//将 s 的 N 个字节复制到 DEST,保证重叠字符串的正确行为。
|
||||
/* Move the data */
|
||||
if (len) memmove(s, s+start, len);
|
||||
s[len] = 0;
|
||||
//给sds设置新的长度
|
||||
sdssetlen(s,len);
|
||||
}
|
||||
|
||||
@ -853,6 +1040,12 @@ void sdssubstr(sds s, size_t start, size_t len) {
|
||||
* s = sdsnew("Hello World");
|
||||
* sdsrange(s,1,-1); => "ello World"
|
||||
*/
|
||||
/**
|
||||
* 将sds切片,提供起始和终止位置,可以是负数表示从结尾开始
|
||||
* @param s sds字符串
|
||||
* @param start 开始
|
||||
* @param end 结束
|
||||
*/
|
||||
void sdsrange(sds s, ssize_t start, ssize_t end) {
|
||||
size_t newlen, len = sdslen(s);
|
||||
if (len == 0) return;
|
||||
@ -863,14 +1056,20 @@ void sdsrange(sds s, ssize_t start, ssize_t end) {
|
||||
newlen = (start > end) ? 0 : (end-start)+1;
|
||||
sdssubstr(s, start, newlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将sds的所有字母变成小写,内部是tolower
|
||||
* @param s sds
|
||||
*/
|
||||
/* Apply tolower() to every character of the sds string 's'. */
|
||||
void sdstolower(sds s) {
|
||||
size_t len = sdslen(s), j;
|
||||
|
||||
for (j = 0; j < len; j++) s[j] = tolower(s[j]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将sds的所有字母变成大写,内部是toupper
|
||||
* @param s sds
|
||||
*/
|
||||
/* Apply toupper() to every character of the sds string 's'. */
|
||||
void sdstoupper(sds s) {
|
||||
size_t len = sdslen(s), j;
|
||||
@ -889,6 +1088,12 @@ void sdstoupper(sds s) {
|
||||
* If two strings share exactly the same prefix, but one of the two has
|
||||
* additional characters, the longer string is considered to be greater than
|
||||
* the smaller one. */
|
||||
/**
|
||||
* 比较两个sds,内部是memcmp
|
||||
* @param s1
|
||||
* @param s2
|
||||
* @return
|
||||
*/
|
||||
int sdscmp(const sds s1, const sds s2) {
|
||||
size_t l1, l2, minlen;
|
||||
int cmp;
|
||||
@ -917,6 +1122,15 @@ int sdscmp(const sds s1, const sds s2) {
|
||||
* requires length arguments. sdssplit() is just the
|
||||
* same function but for zero-terminated strings.
|
||||
*/
|
||||
/**
|
||||
* 将字符串用指定的分割器分割成若干部分,存入sds指针数组,并返回这个指针数组,是简单的字符串匹配,可以使用KMP优化
|
||||
* @param s
|
||||
* @param len
|
||||
* @param sep
|
||||
* @param seplen
|
||||
* @param count
|
||||
* @return
|
||||
*/
|
||||
sds *sdssplitlen(const char *s, ssize_t len, const char *sep, int seplen, int *count) {
|
||||
int elements = 0, slots = 5;
|
||||
long start = 0, j;
|
||||
@ -966,7 +1180,11 @@ cleanup:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放sdssplitlen产生的指针数组和其中的sds的内存
|
||||
* @param tokens
|
||||
* @param count
|
||||
*/
|
||||
/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */
|
||||
void sdsfreesplitres(sds *tokens, int count) {
|
||||
if (!tokens) return;
|
||||
@ -981,6 +1199,13 @@ void sdsfreesplitres(sds *tokens, int count) {
|
||||
*
|
||||
* After the call, the modified sds string is no longer valid and all the
|
||||
* references must be substituted with the new pointer returned by the call. */
|
||||
/**
|
||||
* 处理包含转义字符的二进制字符串
|
||||
* @param s
|
||||
* @param p
|
||||
* @param len
|
||||
* @return
|
||||
*/
|
||||
sds sdscatrepr(sds s, const char *p, size_t len) {
|
||||
s = sdscatlen(s,"\"",1);
|
||||
while(len--) {
|
||||
@ -1005,14 +1230,22 @@ sds sdscatrepr(sds s, const char *p, size_t len) {
|
||||
}
|
||||
return sdscatlen(s,"\"",1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断char c是否是十六进制数,是根据ASCII码判断的
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
/* Helper function for sdssplitargs() that returns non zero if 'c'
|
||||
* is a valid hex digit. */
|
||||
int is_hex_digit(char c) {
|
||||
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F');
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个十六进制字符转换成十进制
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
/* Helper function for sdssplitargs() that converts a hex digit into an
|
||||
* integer from 0 to 15 */
|
||||
int hex_digit_to_int(char c) {
|
||||
@ -1056,6 +1289,12 @@ int hex_digit_to_int(char c) {
|
||||
* quotes or closed quotes followed by non space characters
|
||||
* as in: "foo"bar or "foo'
|
||||
*/
|
||||
/**
|
||||
* 将一行内容读取到sds指针数组,解析配置文件时使用,每个配置项保存在一个sds中,此函数返回一个sds指针数组和其元素个数
|
||||
* @param line
|
||||
* @param argc
|
||||
* @return
|
||||
*/
|
||||
sds *sdssplitargs(const char *line, int *argc) {
|
||||
const char *p = line;
|
||||
char *current = NULL;
|
||||
@ -1175,6 +1414,14 @@ err:
|
||||
*
|
||||
* The function returns the sds string pointer, that is always the same
|
||||
* as the input pointer since no resize is needed. */
|
||||
/**
|
||||
* 将sds中出现在指定字符集中的字符用另一个字符集中的字符代替,要求两个字符集长度相等
|
||||
* @param s
|
||||
* @param from
|
||||
* @param to
|
||||
* @param setlen
|
||||
* @return
|
||||
*/
|
||||
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
|
||||
size_t j, i, l = sdslen(s);
|
||||
|
||||
@ -1191,6 +1438,13 @@ sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
|
||||
|
||||
/* Join an array of C strings using the specified separator (also a C string).
|
||||
* Returns the result as an sds string. */
|
||||
/**
|
||||
* 将若干C字符串用提供的分割器连接起来,产生一个sds
|
||||
* @param argv
|
||||
* @param argc
|
||||
* @param sep
|
||||
* @return
|
||||
*/
|
||||
sds sdsjoin(char **argv, int argc, char *sep) {
|
||||
sds join = sdsempty();
|
||||
int j;
|
||||
@ -1201,7 +1455,14 @@ sds sdsjoin(char **argv, int argc, char *sep) {
|
||||
}
|
||||
return join;
|
||||
}
|
||||
|
||||
/**
|
||||
* 和sdsjoin类似,连接的是若干sds
|
||||
* @param argv
|
||||
* @param argc
|
||||
* @param sep
|
||||
* @param seplen
|
||||
* @return
|
||||
*/
|
||||
/* Like sdsjoin, but joins an array of SDS strings. */
|
||||
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
|
||||
sds join = sdsempty();
|
||||
@ -1219,8 +1480,23 @@ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
|
||||
* the overhead of function calls. Here we define these wrappers only for
|
||||
* the programs SDS is linked to, if they want to touch the SDS internals
|
||||
* even if they use a different allocator. */
|
||||
/**
|
||||
* 分配内存
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
void *sds_malloc(size_t size) { return s_malloc(size); }
|
||||
/**
|
||||
* 重新分配内存
|
||||
* @param ptr
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); }
|
||||
/**
|
||||
* 释放内存
|
||||
* @param ptr
|
||||
*/
|
||||
void sds_free(void *ptr) { s_free(ptr); }
|
||||
|
||||
/* Perform expansion of a template string and return the result as a newly
|
||||
@ -1229,6 +1505,13 @@ void sds_free(void *ptr) { s_free(ptr); }
|
||||
* Template variables are specified using curly brackets, e.g. {variable}.
|
||||
* An opening bracket can be quoted by repeating it twice.
|
||||
*/
|
||||
/**
|
||||
* sds字符串模板
|
||||
* @param template
|
||||
* @param cb_func
|
||||
* @param cb_arg
|
||||
* @return
|
||||
*/
|
||||
sds sdstemplate(const char *template, sdstemplate_callback_t cb_func, void *cb_arg)
|
||||
{
|
||||
sds res = sdsempty();
|
||||
|
@ -140,7 +140,7 @@ static inline size_t sdslen(const sds s) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//sds可用长度
|
||||
//sds可用内存大小
|
||||
static inline size_t sdsavail(const sds s) {
|
||||
//s[-1]的值是flags的值, 要求编译器取消内存对齐优化,按照实际的占用字节数进行对齐,buf的前面是flags
|
||||
unsigned char flags = s[-1];
|
||||
@ -229,7 +229,7 @@ static inline void sdsinclen(sds s, size_t inc) {
|
||||
}
|
||||
}
|
||||
/**
|
||||
*内存占用空间 = 可用空间 + 字符串长度
|
||||
* sds 分配的大小 = sds可用大小 + sds长度
|
||||
* @param s 字符串
|
||||
* @return
|
||||
*/
|
||||
@ -252,7 +252,7 @@ static inline size_t sdsalloc(const sds s) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* 设置字符串的分配的内存
|
||||
* 设置字符串可用内存为新分配的内存
|
||||
* @param s 字符串
|
||||
* @param newlen 新的长度
|
||||
*/
|
||||
|
@ -118,7 +118,11 @@ void *ztrymalloc_usable(size_t size, size_t *usable) {
|
||||
return (char*)ptr+PREFIX_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配内存
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
/* Allocate memory or panic */
|
||||
void *zmalloc(size_t size) {
|
||||
void *ptr = ztrymalloc_usable(size, NULL);
|
||||
@ -131,7 +135,12 @@ void *ztrymalloc(size_t size) {
|
||||
void *ptr = ztrymalloc_usable(size, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配内存 如果返回值为NULL则分配内存失败 否则*usable 设置为可用内存大小
|
||||
* @param size
|
||||
* @param usable
|
||||
* @return
|
||||
*/
|
||||
/* Allocate memory or panic.
|
||||
* '*usable' is set to the usable size if non NULL. */
|
||||
void *zmalloc_usable(size_t size, size_t *usable) {
|
||||
@ -139,12 +148,7 @@ void *zmalloc_usable(size_t size, size_t *usable) {
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
return ptr;
|
||||
}
|
||||
/**
|
||||
* 分配内存 如果返回值为NULL则分配内存失败 否则*usable 设置为可用内存大小
|
||||
* @param size
|
||||
* @param usable
|
||||
* @return
|
||||
*/
|
||||
|
||||
/* Allocation and free functions that bypass the thread cache
|
||||
* and go straight to the allocator arena bins.
|
||||
* Currently implemented only for jemalloc. Used for online defragmentation. */
|
||||
@ -254,7 +258,12 @@ void *ztryrealloc_usable(void *ptr, size_t size, size_t *usable) {
|
||||
return (char*)newptr+PREFIX_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新分配内存并将其归0
|
||||
* @param ptr
|
||||
* @param size 大小
|
||||
* @return
|
||||
*/
|
||||
/* Reallocate memory and zero it or panic */
|
||||
void *zrealloc(void *ptr, size_t size) {
|
||||
ptr = ztryrealloc_usable(ptr, size, NULL);
|
||||
@ -267,7 +276,13 @@ void *ztryrealloc(void *ptr, size_t size) {
|
||||
ptr = ztryrealloc_usable(ptr, size, NULL);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新分配内存 如果为NULL则内存分配失败
|
||||
* @param ptr
|
||||
* @param size 大小
|
||||
* @param usable 可用内存大小
|
||||
* @return
|
||||
*/
|
||||
/* Reallocate memory or panic.
|
||||
* '*usable' is set to the usable size if non NULL. */
|
||||
void *zrealloc_usable(void *ptr, size_t size, size_t *usable) {
|
||||
@ -289,7 +304,10 @@ size_t zmalloc_usable_size(void *ptr) {
|
||||
return zmalloc_size(ptr)-PREFIX_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 释放内存空间
|
||||
* @param ptr
|
||||
*/
|
||||
void zfree(void *ptr) {
|
||||
#ifndef HAVE_MALLOC_SIZE
|
||||
void *realptr;
|
||||
|
Loading…
Reference in New Issue
Block a user