01.数据结构和对象

2.1 SDS -- 定义 :

   在每个sds.h/sdshdr结构表示的 sds 值 :

struts sdshdr{
    
    int  len;  //记录but数组中已使用的字节的数量,等于sds所保存的字符串长度

    int free;  // 记录but数组中未使用的的字节长度

    char but[]; //字节数组,用于保存字符串

}

   free : 属性值为 0 , 表示这个 sds 没有分配任何未使用空间。
   len : 属性值为 5 , 表示这个 sds 表示存了5字节的长字符串。
   but : 属性值为 5 , 表示这个 sds 表示存了具体的字节,最后一个字节保存了
    '\0'。 因为 redis 是 c 语言编写,保存了 c 语言的语法。

   详解:
[图片上传失败...(image-de13cd-1562346060029)]
buf 数组分配了 5 字节未使用的空间,buf 占用了 5 字节的使用了空间。中间自动添加了一个 '\0' 分隔符。

2.1 SDS 与 c 字符串的区别 :

   1. 获取存储长度不同 :
     c 语言不记录长度信息,如果想要获取长度,必须要遍历整个字符串。直到遇到空格符结束。 获取长度的复杂度为 O(n)。
     sds 存储了字符串的长度,所以获取长度的复杂度为 O(1)。
   2. 缓冲溢出 :
     因为c不记录长度,在执行strcat函数时,假设分配了内存,存储的内容比已分配的内存要多,这个时候会出现缓冲区溢出。
     sds 在存储内容时, 先检查存储的内容是否能够存下实际存的值,如果不满足,先将缓冲区扩张成能够存下值的大小,再将真实数据存下去 。
   3. 修改字符串在内存中分配的次数 :
     c 在修改字符串的时候, 如果忘记对内存区域的扩展和减小,都会出现缓冲溢出和泄露。
     SDS 采用了2中方式:
       3.1 空间预分配 :


    // 先进行内存区域进行扩展,然后在执行下面的代码
    public void  test(){
        if(len < 1M){
            程序分配和len属性一样的大小未使用的空间。
        }else if(len > 1M){
            程序分配1M 未使用的空间。
        }
    }

       3.2 惰性空间释放 :
         在修改字符串时,先不会将多余的空间修改掉,用 free 保存下来,等下次再次修改字段长度时,使用这次的空间。
   4. 二进制安全 :
     C 必须存储指定的格式数据。
     SDS 不会对数据限制。
   5. 兼容 c 符串函数 :
     sds 总会在保存数据最后添加一个空字符,是为了重用 库定义的函数。

你可能感兴趣的:(01.数据结构和对象)