Redis-数据结构与对象-简单动态字符串

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33330687/article/details/85715137

1. Redis中的String

在Redis中没有使用c语言的字符串,而是使用了一种叫做简单动态字符串的数据结构,简称SDS,而c中的字符串在Redis只有字面量,且无需对字符串内容修改的时候才使用,其他时候都是使用SDS

例如  set msg “redis”  其中msg和”redis“  底层均为SDS

例如  redisLog("asdasdasd")  这个时候就是使用c语言字符串

2. 数据结构

struct sdshdr{

    //记录buf数组中已经使用的字节数量

    //等于SDS所保存字符串的长度

    int len;

    //记录buf数组中未使用的字节数量

    int free;

    //字节数组,用于保存字符串

    char buf[]

}

3. 使用SDS的优点

3.1. 获取字符串长度更快

SDS因为有len,所以SDS返回字符串长度的时候直接返回len的值,时间复杂度O(1),而如果使用c字符串,那么规则是从开头遍历到\0为止时间复杂度是O(n)

3.2. 杜绝缓冲区溢出

c字符串会因为字符串拼接的时候导致内存溢出,如果忘记之前扩大目标字符串内存大小的话

而SDS是没有这个风险,SDS每次拼接字符串都会预估free是否能装下待拼接的字符串,如果可以则不扩容,如果不行自动扩容,无内存溢出风险

3.3. 减少修改内容时所需要分配内存的次数

因为分配内存这个操作是比较耗费时间的,c字符串每次拼接字符串都是要扩容的,那么如果拼接n次,扩容就需要n次

SDS每次拼接是会自动扩容的,而且不是拼接多少就扩容多少,SDS有个扩容策略

  • 字符串长度小于1m,也就是len的值小于1m,SDS扩容是分配内存free和len将会相同,例如字符串拼接后长度是10,那么SDS的len和free均为10,buf的大小为10+10+1
  • 字符串长度大于1m,每次分配free分配1m  例如SDS长度是50m,那么free是1m  buf大小为50m+1m+1

解释下这个1,SDS和c字符串一样,默认\0结束,为的是兼容c原生的字符串函数,可以直接使用

如果SDS拼接字符串时候free可以放下拼接的字符串,是不需要扩容的,直接存放就行

扫描二维码关注公众号,回复: 5035378 查看本文章

如果SDS使用sdstirm那么回收的内存是不是会释放的,会增加free的数量,这叫做惰性回收

当然,Redis也是有api可以真正回收的内存的函数

3.4. 二进制安全

C字符串是无法存放二进制的,因为遇见空字符是无法解析的,因为遇见空字符会以为是字符串的结尾,导致后面字符无法解析,这就意味着只能存放文本

SDS是可以存放二进制的,这意味着可以存放图片,音频等等信息,因为SDS读取是根据len,而不是去遍历字符串,所以在len的长度之内,是不会有任何对buf数组中字符进行操作的地方

3.5. 兼容部分C函数

因为SDS是以\0结尾,那么这种模式,可以兼容一部分的C函数,因为C函数符合\0结尾字符串就能执行

4. SDS API

函数

作用

时间复杂度

函数

作用

时间复杂度

sdsnew 创建一个包含给定c字符串的SDS O(n) n为给c字符串的长度
sdsempty 创建一个不包含任何内容的空SDS O(1)
sdsfree 释放给定的SDS O(n) n为被释放SDS的长度
sdslen 返回SDS的已使用空间字节数 O(1)
sdsvail 返回SDS未使用的空间字节数 O(1)
sdsup 创建一个给定SDS的副本 copy O(n) n为给定的SDS长度
sdsclear 清空SDS保存字符串内容 O(1) 惰性释放,改free和len即可
sdscat 将给定C字符串拼接到SDS字符串末尾 O(n) n为被拼接的c字符串
sdscatsds 将SDS拼接到另一个SDS末尾 O(n) n为被拼接的SDS字符串
sdscopy 将给定的C字符串复制到SDS中,覆盖原有 O(n) n为被复制的c字符串
sdsgrowzero 用空字符将SDS扩展至给定长度

O(n) n为扩展新增的字节数

sdsrange 保留SDS给定区间内的数据,不在区间内的数据覆盖或清除 O(n) n保留的字节数
sdstrim 接受一个SDS和一个C字符串,从SDS左右两端移除C字符串出现过的字符 O(MN) M是SDS长度,N是c字符串长度
sdscmp 对比两个SDS是否相同 O(n) n为两个SDS中长度小的那个

猜你喜欢

转载自blog.csdn.net/qq_33330687/article/details/85715137