In the source code analysis section, I try to use the native redis source code instead of looking at Huang Jianhong's comments to improve my ability to read the source code. In addition, the redis version is still 3.0
Source code download, you can go here http://download.redis.io/releases/
sdsnew
typedef char *sds;
sds sdsnewlen(const void *init, size_t initlen) {
struct sdshdr *sh;
//Allocate memory
if (init) {
sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
} else {
sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
}
//NULL returned for allocation failure
if (sh == NULL) return NULL;
sh->len = initlen;
sh->free = 0;//It can be seen here that sds initially does not allocate extra space.
if (initlen && init)
//If there is content in init, copy it.
memcpy(sh->buf, init, initlen);
sh->buf[initlen] = '\0';
return (char*)sh->buf;
}
Here, two functions zmalloc and zcalloc are useful. The specific analysis is not covered in detail. The main difference between zmalloc and malloc is that zmalloc allocates more space than malloc (depending on the platform), which is used to store the size that zmalloc is supposed to allocate. The difference between zcalloc and zmalloc is that zmalloc does not initialize memory, but zcalloc does.
sdsempty
Create and return an sds that only holds the empty string ''.
sds sdsempty(void) {
return sdsnewlen("",0);
}
sdsnew
Convert a given c string to sds.
sds sdsnew(const char *init) {
size_t initlen = (init == NULL) ? 0 : strlen(init);
return sdsnewlen(init, initlen);
}
sdsdup
Copy sds
sds sdsdup(const sds s) {
return sdsnewlen(s, sdslen(s));
}
sdsfree
Release sds
void sdsfree(sds s) {
if (s == NULL) return;
zfree(s-sizeof(struct sdshdr));
}
Functions of zfree
Free up memory and modify the memory size used by redis.
sdsupdatelen
? Abandoned function
According to the code, I guess it's to resize the sds
eg.
sds={10,0,"abc"/"abc\0defghi"}
==>
sds={3,7,"abc"}
void sdsupdatelen(sds s) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
int reallen = strlen(s);
sh->free += (sh->len-reallen);
sh->len = reallen;
}
sdsclear
Change sds to an empty string without actually freeing the sds space.
void sdsclear(sds s) {
// Take out sdshdr
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
sh->free += sh->len;
sh->len = 0;
sh->buf[0] = '\0';
}
sdsMakeRoomFor
sdsRemoveFreeSpace
It really frees up the extra space when the inert space is released
sds sdsRemoveFreeSpace(sds s) {
struct sdshdr *sh;
sh = (void*) (s-(sizeof(struct sdshdr)));
// Reallocate the memory so that the buf is only long enough to hold the string contents
// T = O(N)
sh = zrealloc(sh, sizeof(struct sdshdr)+sh->len+1);
// Free space is 0
sh->free = 0;
return sh->buf;
}
sdsAllocSize
Get the space allocated by sds to save the string (len+free+'(len + free + '\ 0'')
size_t sdsAllocSize(sds s) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
return sizeof(*sh)+sh->len+sh->free+1;
}
sdsIncrLen
void sdsIncrLen(sds s, int incr) {
struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
// Make sure the sds space is enough
assert(sh->free >= incr);
// Update properties
sh->len += incr;
sh->free -= incr;
// This assert can be ignored
// Because the previous assert has ensured SH - > Free - incr > = 0
assert(sh->free >= 0);
// Place a new ending symbol
s[sh->len] = '\0';
}