I'm learning the data structure of redis. When I use command [memory usage xxx] to analyse memory usage of a key, I found that the key using raw encoding takes up two bytes more than using embstr encoding. So I read the source code and I found the following code in method [size_t objectComputeSize(robj *o, size_t sample_size);]:
if (o->type == OBJ_STRING) {
if(o->encoding == OBJ_ENCODING_INT) {
asize = sizeof(*o);
} else if(o->encoding == OBJ_ENCODING_RAW) {
asize = sdsZmallocSize(o->ptr)+sizeof(*o);
} else if(o->encoding == OBJ_ENCODING_EMBSTR) {
asize = sdslen(o->ptr)+2+sizeof(*o);
} else {
serverPanic("Unknown string encoding");
}
}
I want to know what + 2 means in the expression that computes memory when using embstr encoding. I found embstr encoding uses sdshdr8, its fixed extra byte should be 4. Is this a bug? My version is redis 4.0, thanks.
Comment From: sundb
2 contain header of sds(1byte) and end of sds(\0).
This code on unstable branch has been modified to a new way of calculating.
Comment From: ertong0129
2 contain header of sds(1byte) and end of sds(
\0).
Thanks for your answer! But I still don't know why the length of sds head is 1. And I think it is should be 3.
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* used */
uint8_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
robj *createEmbeddedStringObject(const char *ptr, size_t len) {
robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr8)+len+1);
struct sdshdr8 *sh = (void*)(o+1);
o->type = OBJ_STRING;
o->encoding = OBJ_ENCODING_EMBSTR;
o->ptr = sh+1;
o->refcount = 1;
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
o->lru = (LFUGetTimeInMinutes()<<8) | LFU_INIT_VAL;
} else {
o->lru = LRU_CLOCK();
}
sh->len = len;
sh->alloc = len;
sh->flags = SDS_TYPE_8;
if (ptr == SDS_NOINIT)
sh->buf[len] = '\0';
else if (ptr) {
memcpy(sh->buf,ptr,len);
sh->buf[len] = '\0';
} else {
memset(sh->buf,0,len+1);
}
return o;
}
Comment From: sundb
@ertong0129 It was indeed wrong, so it was discussed in #6263, and fixed in #9095.
Comment From: ertong0129
@ertong0129 It was indeed wrong, so it was discussed in #6263, and fixed in #9095.
I got it,thank you very much!