在redis中,C字符串(以'\0'结尾的字符数组)只用在一些无需对字符串值进行修改的地方,比如打印日志。其他情况,redis使用SDS - SimpleDynamicString 简单动态字符串,来做。

比如

127.0.0.1:> set testKey "testValue"
OK

键,是一个字符串对象,底层是一个保存着字符串"testKey"的SDS

值也是一个字符串对象,底层是一个保存着字符串"testValue"的SDS

SDS 定义

struct sdshdr {
// 记录buf数组中已使用的字节数,等同于字符串长度(不包括结尾的\0)
int len;
// 记录buf数组中未使用的字节数
int free;
// 实际保存字符串的字节数组
char buf[];
}

比如一个字符串"test":

  len = 4

  free = 0(这个不一定,初始时为0,后续说明)

  buf[] = 't'、'e'、's'、't'、'\0',注意结尾与C相同,也存在'\0',不记入字符串长度

这样做的优势

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

  1. C字符串不记录长度,只能遍历,到\0得到长度,时间复杂度O(n),SDS可以直接记录len为长度,时间复杂度O(1)

2. 兼容部分C字符串的函数

  • 都遵循C字符串以\0结尾的方式,可以重用一部分C字符串函数库的方法

3. 减少修改字符串时带来的内存重分配次数

  • 通过每次增长或减短字符串时,设置free,使字符串预留出一部分空间,而不是每次都精确到字符串的长度。在频繁修改字符串的环境中可以减少内存重新分配的操作
  • 具体涉及到两种情况:变长、变短。
  • 变长:空间预分配

    • 如果修改后的字符串长度小于 1MB,则程序分配大小和len相同的未使用空间给free

      • 比如"test"修改为"testAgain",则len=9、free=9、buf[] 数组大小为 9+9+1(\0)=19字节
    • 如果修改后的字符串长度大于等于 1MB,则程序分配固定的 1MB给free

      • 比如一个0.7MB的字符串扩成了7MB,则len=7MB、free=1MB、buf[] 数组大小为 9MB + 9MB + 1B
    • 如果修改后的字符串长度能被len+free放下,则此次修改字符串就不需要重新分配空间了
  • 变短:惰性空间释放

    • 变短后的字符串,变短的长度被保存在free中,未来如果有变长操作,则可以直接使用。

      • 比如"test"修改为"t",则len=1、free=3、buf[] 数组大小为 1+3+1=5字节,与变短之前的4+0+1相同

同时SDS提供实时释放未使用空间的api

其他特点

SDS的api都是二进制安全的,所有SDS的api都会用处理二进制的方式处理buf[]中的数据,不会特殊处理。

比如一个字符串内容为"test\0andmore",其内容不会因为有\0而被截断

redis_简单动态字符串的更多相关文章

  1. Redis的简单动态字符串实现

    Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类 ...

  2. Redis数据结构之简单动态字符串SDS

    Redis的底层数据结构非常多,其中包括SDS.ZipList.SkipList.LinkedList.HashTable.Intset等.如果你对Redis的理解还只停留在get.set的水平的话, ...

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

    本文为读<Redis设计与实现>的记录.该书以Redis2.9讲解Redis相关内容.请注意版本差异. Redis使用C语言实现,他对C语言中的char类型数据进行封装,构建了一种简单动态 ...

  4. redis 系列3 数据结构之简单动态字符串 SDS

    一.  SDS概述 Redis 没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,并将SDS用作Redis的默 ...

  5. 图解Redis之数据结构篇——简单动态字符串SDS

    图解Redis之数据结构篇--简单动态字符串SDS 前言     相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...

  6. Redis中的简单动态字符串

    Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SD ...

  7. Redis---SDS(简单动态字符串)

    Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类 ...

  8. Redis数据类型之SDS简单动态字符串

    一,简单的动态字符串 1,Redis自己构建了一种名为简单动态字符串的抽象类型,并将SDS用作Redis的默认字符串表示, 2,在redis的数据库里面,包含字符串值的键值对在底层都是由SDS实现的 ...

  9. 《Redis设计与实现》阅读笔记(二)--简单动态字符串

    简单动态字符串 Redis只在一些无需对字符串进行修改的地方使用C字符串,大部分时候使用简单动态字符串(simple dynamic string, SDS),字符串的抽象类型.二进制安全,可以存放任 ...

随机推荐

  1. 字符IO流

    输入 FileReader的用法: 1. 找到目标文件 2. 建立数据的输入通道 3. 读取数据 4. 关闭资源 具体实例:从硬盘中读取文件 输出 FileWriter的使用步骤: 1. 找到目标文件 ...

  2. ARTS打卡计划第二周-Tips-mysql-binlog-connector-java的使用

    最近发现一个挺不错的框架mysql-binlog-connector-java,可以实时监控binlog的变化. 首先检查mysql的binlog是否开启,在开启的情况下: 引入依赖 <depe ...

  3. tensorflow 升级到1.9-rc0,tensorboard 报错:TypeError: GetNext() takes exactly 1 argument (2 given)

    Exception in thread Reloader:Traceback (most recent call last):  File "/usr/lib/python2.7/threa ...

  4. Harbor私有镜像仓库(上)

    上图配置为工作环境 特别注意:win10现在不允许使用私有ca证书,到时登录浏览器会失败,可以选用火狐浏览器. 创建自己的CA证书 openssl req -newkey rsa:4096 -node ...

  5. python第一周语言基础

    控制语句 if语句,当条件成立时运行语句块.经常与else, elif(相当于else if) 配合使用. for语句,遍历列表.字符串.字典.集合等迭代器,依次处理迭代器中的每个元素. while语 ...

  6. del_cursor 批量删除游标

    declare   cursor [del_cursor] is select a.*, a.rowid row_id from [table_name] a order by a.rowid;   ...

  7. Linux中文乱码 - - 更改Linux字符集

     查看当前系统默认采用的字符集: # locale 在RedHat/CentOS系统下,记录系统默认使用语言的文件是/etc/sysconfig/i18n,如果默认安装的是中文的系统,i18n的内容如 ...

  8. java、asp.net 通用分页码函数

    <script type="text/javascript"> $(document).ready(function(){ ajaxGetPaging(1); }); ...

  9. django之组件

    (Django) 组件:本质上就是将一个写好的功能模块的html文件直接引入html目标文件,利用其功能. 标准语法: {% include 'html文件名' %} 如:{% include 'na ...

  10. jsp请求java返回pdf、excel与word

    1,返回pdf关键代码 /** * @todo * @param * @date 2019年3月8日 * @author yanan */ @RequestMapping("/getPdf& ...