Redis原理:动态字符串SDS

(课程总结自b站黑马程序员课程)

一、引言

Redis中保存的Key是字符串,value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。

不过Redis没有直接使用C语言中的字符串,因为C语言字符串存在很多问题:

①获取字符串长度的需要通过运算

②非二进制安全:指‘/0’字符的读取问题。

③不可修改 Redis构建了一种新的字符串结构,称为简单动态字符串(Simple Dynamic String),简称SDS。

二、源码分析

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[];
};

#define SDS_TYPE_5  0
#define SDS_TYPE_8  1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4

以sdshdr8为例进行分析:

struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; //已使用字符串字节数,不包括结束标志
    uint8_t alloc; //申请总字节数,不包括结束标志
    unsigned char flags; //SDS头信息
    char buf[];
};

这个的uint8_t len记录的字节长度,8位二进制的最大值为255,也就是可以记录最大255字节数的字符串。c语言中char的占用的字节数为1,也就是sdshdr8可以记录长度为255的字符串。

三、结构分析

例如,一个包含字符串“name”的sds结构如下:

SDS之所以叫做动态字符串,是因为它具备动态扩容的能力,例如一个内容为“hi”的SDS:

 

假如我们要给SDS追加一段字符串“,Amy”,这里首先会申请新内存空间:

如果新字符串小于1M,则新空间为扩展后字符串长度的两倍+1;

如果新字符串大于1M,则新空间为扩展后字符串长度+1M+1。称为内存预分配。

(申请分配内存需要Linux从用户态切换到内核态,这个过程需要运用的资源相当多,内存预分配可以在很大程度上节省资源分配)

四、优点 

①获取字符串长度的时间复杂度为O(1)。

②支持动态扩容。

③减少内存分配次数。

④二进制安全。文章来源地址https://uudwc.com/A/128On

原文地址:https://blog.csdn.net/m0_64694079/article/details/132766682

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

上一篇 2023年09月08日 22:13
英语单词(1)
下一篇 2023年09月08日 22:14