在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. python字符串 列表 元组 字典相关操作函数总结

    1.字符串操作函数 find 在字符串中查找子串,找到首次出现的位置,返回下标,找不到返回-1 rfind 从右边查找 join 连接字符串数组 replace 用指定内容替换指定内容,可以指定次数 ...

  2. 知识点---animate()动画滞后执行的解决方案

    jQuery动画: animate 容易出现连续触发.滞后反复执行的现象: 针对 jQuery 中 slideUp.slideDown.animate 等动画运用时出现的滞后反复执行等问题的解决方法有 ...

  3. jmeter学习笔记--概述

    jmeter:概述 是什么? jmeter是Apache 公司使用java开发的一款测试工具 为什么? 高效.功能强大 模拟一些高并发或多次循环等特殊场景 怎么用? 1.下载jmeter,解压缩 2. ...

  4. windows上不能启动Apache,遇到错误的方法之一

    最近在2008服务器上安装apache,出现了No installed ConfigArgs for the service "Apache2.4"这个错误. 启动不了,重装了一样 ...

  5. Android 添加第三方jar包

    1,拷贝jar包到项目的\app\libs文件夹下. 2,打开项目下的build.gradle(Module:app)文件,在“dependencies {}”中添加“compile files('l ...

  6. Linux - 其他命令

    其他命令 目标 查找文件 find 软链接 ln 打包和压缩 tar 软件安装 apt-get 01. 查找文件 find 命令功能非常强大,通常用来在 特定的目录下 搜索 符合条件的文件 序号 命令 ...

  7. php+javascript实现的动态显示服务器运行程序进度条功能示例

    本文实例讲述了php+javascript实现的动态显示服务器运行程序进度条功能.分享给大家供大家参考,具体如下: 经常有这样的业务要处理,服务器上有较多的业务需要处理,需要分批操作,于是就需要一个提 ...

  8. 20175314 《Java程序设计》第七周学习总结

    20175314 <Java程序设计>第七周学习总结 教材学习内容总结 第八章:常用实用类 String()类代表字符串:Java 程序中的所有字符串字面值(如 "abc&quo ...

  9. tensorflow实现二分类

    读万卷书,不如行万里路.之前看了不少机器学习方面的书籍,但是实战很少.这次因为项目接触到tensorflow,用一个最简单的深层神经网络实现分类和回归任务. 首先说分类任务,分类任务的两个思路: 如果 ...

  10. 【搬运】 Page Object 官方文档 (新增了Widget特性)

    Appium Java client has facilities which components to [Page Object](https://github.com/SeleniumHQ/se ...