# /

# embstr源码

#define LRU_BITS 24
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
9
10
struct RedisObject {
  int4 type; // 4bits
  int4 encoding; // 4bits
  int24 lru; // 24bits
  int32 refcount; // 4bytes
  void *ptr; // 8bytes,64-bit system
} robj;
1
2
3
4
5
6
7

image.png
RedisObject占用16字节,sdshdr8占用4字节,如果保存的值小于44字节,总共只需要20+44=64字节。
这样embstr编码的RedisObject所有数据可保存在一块连续的64字节的内存中。
1、节省内存空间。
2、内存分配更快,只需分配一次64字节。
3、查询速度更快。

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
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[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
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

# embstr编码转换

> set key hello
OK
> object encoding key
"embstr"
> append key world //append修改embstr,被转换为raw
(integer) 10
> object encoding key
"raw"
> set key helloworld //set覆盖embstr
OK
> object encoding key
"embstr"
1
2
3
4
5
6
7
8
9
10
11
12