制作网站方法,网站开发干啥的,番禺网站建设服务,旅游网站技术流程图#xff08;课程总结自b站黑马程序员课程#xff09;
一、引言
Redis中保存的Key是字符串#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。
不过Redis没有直接使用C语言中的字符串#xff0c;因为C语言字符串存在很多问题课程总结自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则新空间为扩展后字符串长度1M1。称为内存预分配。
申请分配内存需要Linux从用户态切换到内核态这个过程需要运用的资源相当多内存预分配可以在很大程度上节省资源分配 四、优点
①获取字符串长度的时间复杂度为O(1)。
②支持动态扩容。
③减少内存分配次数。
④二进制安全。