sds _sdsnewlen(constvoid *init, size_t initlen, int trymalloc) { void *sh; sds s; /* sdsReqType 获取需要使用的sdshdr类型*/ char type = sdsReqType(initlen); /* Empty strings are usually created in order to append. Use type 8 * since type 5 is not good at this. */ if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8; /* sdsHdrSize 获取该类型的结构体大小*/ int hdrlen = sdsHdrSize(type); unsignedchar *fp; /* flags pointer. */ size_t usable;
/* Return ASAP if there is enough space left. */ if (avail >= addlen) return s;
len = sdslen(s); sh = (char*)s-sdsHdrSize(oldtype); newlen = (len+addlen); assert(newlen > len); /* Catch size_t overflow */ /* SDS_MAX_PREALLOC为1024*1024 */ if (newlen < SDS_MAX_PREALLOC) newlen *= 2; else newlen += SDS_MAX_PREALLOC; /* 获取新长度的sdshdr类型 */ 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. */ if (type == SDS_TYPE_5) type = SDS_TYPE_8;
hdrlen = sdsHdrSize(type); assert(hdrlen + newlen + 1 > len); /* Catch size_t overflow */ /* 同样申请hdrlen+newlen+1大小的空间,但根据类型是否更改进行不同操作*/ if (oldtype==type) { newsh = s_realloc_usable(sh, hdrlen+newlen+1, &usable); if (newsh == NULL) returnNULL; s = (char*)newsh+hdrlen; } else { /* Since the header size changes, need to move the string forward, * and can't use realloc */ newsh = s_malloc_usable(hdrlen+newlen+1, &usable); if (newsh == NULL) returnNULL; memcpy((char*)newsh+hdrlen, s, len+1); s_free(sh); s = (char*)newsh+hdrlen; s[-1] = type; sdssetlen(s, len); } usable = usable-hdrlen-1; if (usable > sdsTypeMaxSize(type)) usable = sdsTypeMaxSize(type); sdssetalloc(s, usable); return s; }
embstr
当字符串长度小于等于44字节时,使用的是embstr编码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
redis> set a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa OK
redis> strlen a (integer) 44
redis> object encoding a "embstr"
redis> set a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa OK