在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. Java8 之stream

    总概述:Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操 ...

  2. java 两个List集合各种情况对比处理

    Lambda作为函数式编程中的基础部分,在其他编程语言(例如:Scala)中早就广为使用,但在JAVA领域中发展较慢,直到java8,才开始支持Lambda. 抛开数学定义不看,直接来认识Lambda ...

  3. mysql修改联合主键

    参考 https://blog.csdn.net/BockSong/article/details/80933477 alter table TABNAME drop primary key; alt ...

  4. step_by_step_xUnit_Net_ABP

    这段日子的开发一直使用Asp.net Boilerplate ,称之为项目模板自然就有开发中常用的功能,测试框架也在其中,土牛的ABP源代码都有通过测试,很遗憾的是我之前没有写过测试,不会就要去找资料 ...

  5. mysql 开启root外部链接权限

    mysql给root开启远程访问权限,修改root密码 1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问. 这对于 Web-Server ...

  6. 第七周博客作业 <西北师范大学| 周安伟>

    第七周博客作业 助教博客链接:https://home.cnblogs.com/u/zaw-315/ 本周无评作业 查看了同学们提交的对实验四的附加实验项目互评.其中对博文结构,内容来评价是否符合作业 ...

  7. Mybateis mapper 接口 example 用法

    注意:希望通过此篇文章分享 可以使大家对mapper接口以及example 用法更加深入理解 MyBatis的Mapper接口以及Example的实例函数及详解 一.mapper接口中的方法解析 ma ...

  8. 分析abex-crackme#1

    1.分析环境2.运行程序,了解大致的运行过程3.运行Ollydbg调试程序3.1.分析结果简述4.破解4.1.方法一4.2.方法二5.运行结果6.与书中不同之处 1.分析环境 操作系统:Win10 1 ...

  9. PL/SQL链接Oracle出现乱码

    1.用Pl/sql时,中文注释是乱码,需要查看下oracle server端的字符集. SQL语句:select userenv('language') from dual 结果:SIMPLIFIED ...

  10. CentOS 7 minimal网络配置

    centos最小化安装没有ifconfig命令,可以使用  ip addr  查看网络信息,习惯ifconfig的用户,则使用 yum -y install net-tools 即可 ; 如果yum不 ...