小白的Redis学习(一)-SDS简单动态字符串

本文为读《Redis设计与实现》的记录。该书以Redis2.9讲解Redis相关内容。请注意版本差异。


  Redis使用C语言实现,他对C语言中的char类型数据进行封装,构建了一种简单动态字符串(以下简称SDS),该字符串的结构如下

struct sdshdr{
  //记录buf数组中已使用字节的数量
  //获取字符串的长度时,就是直接返回的这个字段的值
  int len; //记录buf数组中未使用字节的数量   int free;   //字节数组,用于保存字符串   char buf[]; }

  SDS遵循C语言中,字符串以空字符结尾的惯例。该空字符会在buf[]中占一位,但是不会统计到字符串长度 len中,这个空字符对于编程者来说,是透明的。

  如Redis在SDS中存储的方式可能为

    len = 5;

    free = 0;

    buf = {'R','e','d','i','s','\0'}

  free是指buf中的预留长度。他的值遵循以下三种规则

  1) buf数组删除掉一部分时,buf的长度不会立即改变,删除的长度会先累加进free的值中。

  2) buf数组新增一部分时,若free的值大于新增的长度,则free减去新增的长度,若free小于新增的长度,则对buf进行扩容,free = len + 新增的长度 ,buf = 2 * free + 1,加的1是'\0' 空字符的值

  3) free的最大值不超过1M

  总结:SDS的扩容遵循了类似于hashMap扩容的*2规则,通过增加空间复杂度,减少了时间复杂度,空间最大的花费忍耐度是1M。

  SDS与C语言中的普通字符串的一个大的区别是:SDS允许字符串的中间出现空字符。SDS字符串的结束标识是根据len的大小来进行判断的,末尾额外的增加一个空字符,只是为了使用一部分C语言中提供的API。这样,SDS就可以储存一些图像、音频、视频、压缩文件这样的二进制数据。而C语言中的一般字符串遇到空字符就判断字符串结束。无法存储这些二进制文件。


  总的来说,SDS的优点如下:

  1) 常数复杂度的获取字符串长度 

  2) 杜绝缓冲区溢出

  3) 减少修改字符串时所需的内存分配次数

  4) 二进制存储安全

  5) 兼容部分C字符串函数

posted @ 2019-02-19 12:57  有营养的yyl  阅读(...)  评论(...编辑  收藏