redis源码分析 --- 简单动态字符串sds

简单动态字符串sds

redis没有直接使用c语言标准库中传统的字符串表示,而是自己构建了简单字符串(sds)的抽象类型,它的特点是:可在常数时间复杂度获取字符串长度,因为sds结构中保存了数据的长度、杜绝缓冲区溢出可动态扩展内存减少重复修改字符串带来的内存重新分配次数惰性释放内存空间二进制安全兼容部分c语言字符串函数。 

  • sds定义

typedef char *sds;

redis采用一段连续的内存来存储数据, char*类型和传统的c语言字符串类型兼容。但是,sds和char*不同之处是,sds是二进制安全的,它可以存储任意二进制数据,不像C语言字符串那样以‘\0’来标识字符串结束,sds结构的巧妙之处是在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 {
    /*! 记录buf数组中已使用的字节的数量,等于sds所保存字符串的长度*/
    uint8_t len; /* used */
    /*! 记录buf数组中未使用的字节数量,这个长度不包含sds头部和'\0'结束符长度*/
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

为了节省空间,sds另外还定义了sdshdr16、sdshdr32、sdshdr64结构,分别保存不同长度的数据。

sds的数据结构示例图为:

redis源码分析 --- 简单动态字符串sds_第1张图片

sds与c字符串相比的一些特点:

  • 可在常数时间复杂度内获取字符串的长度,因为sds的头部结构中存储了字符串的长度。
  • 杜绝缓冲区溢出,在修改sds内容时,sds的api先判断存储空间是否足够,之后再决定是否进行动态分配。
  • 减少修改字符串时带来的内存重分配次数,采用了空间预分配与惰性空间释放。
  • 二进制安全。
  • 兼容部分c语言字符串函数。

 

你可能感兴趣的:(redis源码分析)