【Redis】01底层数据结构-SDS

SDS

全称

simple dynamic string,简单动态字符串

应用场景
SDS的定义
//sds.h
typedef char *sds;  

//
struct sdshdr {
    //记录buf数组中已经使用的字节数量
    //等于记录sds中保存的字符串长度
    int len;   
    //记录buf数组中未使用的字节数量
    int free;    
    //字节数组;用来保存字符串
    char buf[]; 
};

SDS结构图

image.png

说明:

  • len为5,表示这个sds长度为5字节。
  • free为2,表示这个sds还有2个字节未使用的空间。
  • buf是一个char[]的数组,分配了(len+1+free)个字节的长度,前len个字节保存着’R’、’e’、’d’、’i’、’s’这5个字符,接下来的1个字节保存着’\0’,剩下的free个字节未使用。
SDS的优点
  • 减少因修改字符串带来的内存重新分配的次数:
    • 空间分配:修改字符串时会对新的长度进行判断,如果小于1MB(SDS_MAX_PREALLOC)直接将长度*2;如果大于等于1MB则会在新的长度上+1MB(SDS_MAX_PREALLOC)
    • 惰性释放:字符缩短时空出来的内存不会立即回收,记录到free字段中留到后面使用
  • 二进制安全:
    因为传统C字符串符合ASCII编码,这种编码的操作的特点就是:遇零则止 。即,当读一个字符串时,只要遇到’\0’结尾,就认为到达末尾,就忽略’\0’结尾以后的所有字符。因此,如果传统字符串保存图片,视频等二进制文件,操作文件时就被截断了。而SDS表头的buf被定义为字节数组,因为判断是否到达字符串结尾的依据则是表头的len成员,这意味着它可以存放任何二进制的数据和文本数据,包括’\0’
  • 获得字符串长度的操作复杂度为O(1)
  • 杜绝缓冲区溢出: 因为SDS表头的free成员记录着buf字符数组中未使用空间的字节数,所以,在进行APPEND命令向字符串后追加字符串时,如果不够用会先进行内存扩展,在进行追加。
  • 兼容C部分函数
posted @ 2020-04-28 09:34  abs_征召不老  阅读(106)  评论(0)    收藏  举报