Redis 数据结构-String(SDS)

26 阅读2分钟

Redis为什么要自己实现SDS

  1. C语言的字符串都是以'\0'结尾,当需要获取字符串长度时,都是通过遍历字符串知道遇到了'\0',所以C语言获取字符串长度的时间复杂度是o(n)

  2. 第一点说了,C语言是以'\0'作为字符串的结尾,所以当字符串'hello \0 world'作为一个字符串时,C语言只能读取到'hello',后面的字符串都会被忽略,所以C语言字符串只能支持普通的文本,不能支持图片,文件,视频等格式的二进制数据

  3. C语言的许多字符串函数都需要开发者保证字符串有足够的空间,比如C语言的strcat(char* dest, const char* src)函数,将src的内容拼接到dest后面,需要保证dest有足够的空间,否则程序就有可能产生缓冲区不够而退出

    如上所述,C语言的字符串有这些缺点,所以Redis自己实现了字符串的对象SDS

SDS如何实现的

image.png

这是Redis实现的SDS的数据结构

  • len:表示字符串的长度,所以获取字符串的长度时间复杂度时O(1)
  • alloc:表示字符串的缓冲区长度,当字符串需要做一些连接操作时,就可以通过alloc-len去判断是否还有空间,如果没有就可以预分配空间,再进行连接操作
  • flags:表示sds的不同类型,有sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64这么集中类型,不同的类型用来表示不同大小的字符串,例如 sdshdr16 和 sdshdr32 这两个类型,sdshdr16通过uint16 len, uint16 alloc来定义属性,而sdshdr32 通过uint32 len, uint32 alloc来定义属性,这样当字符串的长度不超过2的16次方时,就通过sdshdr16来表示,这样就可以节省一定的内存空间
  • buf:存储字符的自介数组