redis-sds复习

redis - sds

之前本来跟着付磊团队在redis组做开发,要做技术分享,所以写了这个文章,后来发生组织架构变动去做自研缓存kcache了。但这篇sds实现还是可以沉淀一下。

总体代码逻辑清晰简单,过一遍重要结构

sds内存结构

1
2
3
4
5
6
7
typedef char *sds;
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[];
};

sds内存结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// init为c类型字符串,initlen为其长度
sds sdsnewlen(const void *init, size_t initlen) {
void *sh;
sds s;
char type = sdsReqType(initlen);
// 算出其头部偏移量
int hdrlen = sdsHdrSize(type);
unsigned char *fp; /* flags pointer. */

sh = s_malloc(hdrlen+initlen+1);
if (sh == NULL) return NULL;
if (init==SDS_NOINIT)
init = NULL;
else if (!init)
memset(sh, 0, hdrlen+initlen+1);
// 返回的指针为指向真正字符串的位置
s = (char*)sh+hdrlen;
fp = ((unsigned char*)s)-1;
switch(type) {
...
case SDS_TYPE_8: {
SDS_HDR_VAR(8,s);
sh->len = initlen;
sh->alloc = initlen;
*fp = type;
break;
}
...
}
...
// 按c类型字符串的方法存
s[initlen] = '\0';
return s;
}

object - sds内存结构

1
2
3
4
5
6
7
8
9
10
// object.c
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
} robj;
1
2
3
4
5
6
7
8
// object.c
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
robj *createStringObject(const char *ptr, size_t len) {
if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)
return createEmbeddedStringObject(ptr,len);
else
return createRawStringObject(ptr,len);
}

object-sds