/* * 根据给定的初始化字符串 init 和字符串长度 initlen * 创建一个新的 sds * * 参数 * init :初始化字符串指针 * initlen :初始化字符串的长度 * * 返回值 * sds :创建成功返回 sdshdr 相对应的 sds * 创建失败返回 NULL * * 复杂度 * T = O(N) */ /* Create a new sds string with the content specified by the 'init' pointer * and 'initlen'. * If NULL is used for 'init' the string is initialized with zero bytes. * * The string is always null-termined (all the sds strings are, always) so * even if you create an sds string with: * * mystring = sdsnewlen("abc",3"); * * You can print the string with printf() as there is an implicit \0 at the * end of the string. However the string is binary safe and can contain * \0 characters in the middle, as the length is stored in the sds header. */ sds sdsnewlen(constvoid *init, size_t initlen) {
structsdshdr *sh;
// 根据是否有初始化内容,选择适当的内存分配方式 // T = O(N) if (init) { // zmalloc 不初始化所分配的内存 sh = zmalloc(sizeof(struct sdshdr)+initlen+1); } else { // zcalloc 将分配的内存全部初始化为 0 sh = zcalloc(sizeof(struct sdshdr)+initlen+1); }
/* Enlarge the free space at the end of the sds string so that the caller * is sure that after calling this function can overwrite up to addlen * bytes after the end of the string, plus one more byte for nul term. * * Note: this does not change the *length* of the sds string as returned * by sdslen(), but only the free buffer space we have. */ /* * 对 sds 中 buf 的长度进行扩展,确保在函数执行之后, * buf 至少会有 addlen + 1 长度的空余空间 * (额外的 1 字节是为 \0 准备的) * * 返回值 * sds :扩展成功返回扩展后的 sds * 扩展失败返回 NULL * * 复杂度 * T = O(N) */ sds sdsMakeRoomFor(sds s, size_t addlen) {
structsdshdr *sh, *newsh;
// 获取 s 目前的空余空间长度 size_tfree = sdsavail(s);
size_t len, newlen;
// s 目前的空余空间已经足够,无须再进行扩展,直接返回 if (free >= addlen) return s;
// 获取 s 目前已占用空间的长度 len = sdslen(s); sh = (void*) (s-(sizeof(struct sdshdr)));