RedisObject
Redis
中的所有数据都是通过 RedisObject
来表示的,它的结构如下:
struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS;
int refcount;
void *ptr;
};
type
表示数据类型,如string
、hash
、list
、set
、zset
、bitmap
等,占用4bit
- 这些类型在
Redis
内部有预定义OBJ_STRING 0
OBJ_LIST 1
OBJ_SET 2
OBJ_ZSET 3
OBJ_HASH 4
- 这些类型在
encoding
表示编码方式,如int
、embstr
、raw
、ht
、ziplist
、intset
、skiplist
、quicklist
、stream
等,占用4bit
OBJ_STRING
:raw
、embstr
、int
OBJ_LIST
:quicklist
OBJ_SET
:intset
、ht
OBJ_ZSET
:ziplist
、skiplist
、ht
OBJ_HASH
:ziplist
、ht
lru
表示该对象最后一次被访问的时间,占用24bit
refcount
表示引用计数,被引用一次就加1
,不被引用了就减1
,直到0
,占用4bit
ptr
表示指向实际数据的指针,占用8bit
所以光这一个头部信息占用 16
个字节
简单动态字符串 SDS
redis
中的 key
是个字符串
但是 redis
没有使用 c
中的字符串,而是自己实现了一套字符串,叫做 SDS
SDS
全称 Simple Dynamic String
简单动态字符串,由两部分组成,如图所示:
代码结构如下:
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len;
uint8_t alloc;
unsigned char flags;
char buf[];
};
其中 len
、alloc
、flags
是头部信息
len
表示内容使用占用的字节,本身占用1
个字节alloc
表示分配的字节,本身占用1
个字节flags
是个头类型,用来控制头大小,占用1
个字节:SDS_TYPE_5 0
不常用SDS_TYPE_8 1
SDS_TYPE_16 2
SDS_TYPE_32 3
SDS_TYPE_64 4
buf
是个柔性数组,保存的是字符串的地址,默认不占用内存
SDS 与 c 字符串的区别
为什么要自己实现一套字符串呢?
因为 c
中的字符串是以