【redis】sds数据结构
本⽂从源码介绍sds的数据结构。
sds是redis中对传统字符串的封装,在其上加⼊了长度等信息。⽤于redis中key等字符串类型数据的存储。
1 sds的数据结构
typedef char *sds;
/* 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[];
};
如上代码,sds实际上有五类,具体的类型由flags来确定,其内存形式如下:
len保存当前数据已占⽤的字节数;
alloc保存数据可⽤的全部内存空间(实际上数据部分占⽤的字节数是alloc + 1);
alloc - len 是当前可⽤空间;
flags表⽰sds的类型,该类型决定了 len 和 alloc所占⽤的⼤⼩。
对于sdshdr5, head部分只有⼀个字节,其中⾼5位存储的是len,低三位是sdshdr5的类型。
redis八种数据结构sds总是保持数据最后的⼀个字节是0,同时,提供的sds指针是指向了数据部分其实的位置,所以sds
可以直接被⽤于c的字符串函数。
2 sds的操作
主要的操作包括新建、赋值、追加。⼀般来讲,就是扩容和缩容两个操作,对于扩容,扩容后<1M的字符串,每次扩容都在扩容之后基础上翻倍;>=1M,则每次再多扩1M。⼤多情况下,被扩容的内存⼤概率再次被扩容,这样做可以减少扩容次数,从⽽提⾼性能。
扩容不会产⽣ sdshdr5 类型的sds,这是因为 sdshdr5 没有保存 容量,不能额外扩容,只能每次需要的时候都进⾏扩充。
扩容会改变字符串类型,旧sds不可⽤,需要使⽤新的sds。⽽缩容则不会改变字符串类型。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论