redis系列4---底层数据结构之简单动态字符串(SDS)

本文深入探讨了简单动态字符串(SDS)在Redis中的关键作用,特别是在字符串值的高效存储、避免缓冲区溢出及优化内存重分配方面。SDS通过其独特的结构,如len和free字段,实现了字符串长度的快速获取和空间预分配,从而提高了Redis的性能。
哪里使用了C字符串?
    不需要修改的字符串字面量
哪里用到了SDS?
    保存数据库中的字符串值(包括key和value)
    缓冲区(AOF缓冲区、输入输出缓冲区)
认识SDS?
    struct sdshdr {
        unsigned int len;//记录buf数组中已使用字节的数量,等于SDS所保存字符串的长度
        unsigned int free;//记录buf数组中未使用字节的数量
        char buf[];//字节数组,用于保存字符串
    }
    注意:SDS遵循C字符串以空字符结尾的惯例,以便于直接重用一部分C字符串函数库里函数。
SDS与C字符串的区别?
    获取字符串长度为O(1)/C为O(N)
    SDS杜绝缓冲区溢出(SDS API在修改时,会先检查空间是否满足要求,不满足会自动扩展)
        此处留问题:如何扩展?空间分配策略?
    减少修改字符串时带来的内存重分配次数-->通过free属性实现以下两种优化策略
        空间预分配:用于优化SDS字符串增长操作。
            不仅分配修改所必须要的空间,还会分配额外的未使用空间。
            未使用空间数量规则如下:
                修改后的SDS长度<1MB:free=len
                修改后的SDS长度>1MB:free=1MB
        惰性空间释放:用于优化SDS字符串缩短操作。
            不会立即回收多出来的字节,而是用free属性记录起来,等待将来使用,有API可以真正释放空间。
    二进制安全
SDS API
    sdsnew:创建一个包含给定C字符串的SDS,O(N),N为给定C字符串的长度
    sdsempty:创建一个不包含任何内容的空SDS,O(1)
    sdsfree:释放给定的SDS,O(N),N为被释放SDS的长度
    sdslen:返回SDS的已使用空间字节数,O(1),len属性
    sdsavail:返回SDS的未使用空间字节数,O(1),free属性
    sdsdup:创建一个给定SDS的副本,O(N),N为给定SDS的长度
    sdsclear:清空SDS保存的字符串内容,O(1)
    sdscat:将给定C字符串拼接到SDS字符串的末尾,O(N),N为被拼接C字符串的长度
    sdscatsds:将给定SDS字符串拼接到另一个SDS字符串的末尾,O(N),N为被拼接SDS字符串的长度
    sdscpy:将给定的C字符串复制到SDS里面,覆盖SDS原有的字符串,O(N),N为被复制C字符串的长度
    sdsgrowzero:用空字符将SDS扩展至给定长度,O(N),N为扩展新增的字节数
    sdsrange:保留SDS给定区间内的数据,不在区间内的数据会被覆盖或清除,O(N),N为被保留数据的字节数
    sdstrim:接受一个SDS和一个C字符串作为参数,从SDS左右两端分别移除所有在C字符串中出现过的字符,O(M*N),M为SDS长度,N为给定c字符串的长度
    sdscmp:对比两个SDS字符串是否相同,O(N),N为两个SDS中较短的那个SDS的长度复制代码

转载于:https://juejin.im/post/5bd15c2af265da0aca334e09

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值