redis学习 -- 简单动态字符串
Redis没有使用C语言字符串的形式,通过’\0’作为结尾,而是使用了简单动态字符串(simple dynamic string)。
当Redis使用的字符串不需要修改字符串的内容的时候,可以使用C语言提供的字符串,当需要修改内容的时候就使用的是简单动态字符串。Redis键值对的操作中,都是使用的简单动态字符串的方式。
这里可以把简单动态字符串理解成一个对象,这个对象的底层保存着一个字符串。
SDS定义
在sds.h/sdshdr结构体中定义了SDS的值
struct sdshdr {int len;int free;char buf[];
};
如果我们使用SDS定义一个SDS内容为“Redis”的对象,则组织结构如下图所示
- free属性值为0,表示这个SDS没有分配任何没有使用的空间。
- len属性的值是5,表示这个SDS保存了一个五字节长的字符串。
- buf属性是一个char类型的数组,数组里面保存了字符串的值,并且以’\0’结束。
SDS和C字符串的区别和优势
常数时间复杂度获取字符串长度
C字符串获取字符串长度需要遍历,耗时。
SDS记录了长度,可以在O(1)的时间复杂度获取字符串长度。
杜绝缓冲区溢出
在C语言中使用strcat(dest, src)的时候,用户自身需要保证dest的空间要大于拼接之后的内存空间。但是很多时候由于疏忽导致内存溢出。SDS解决了这个问题,使用SDS的APIsdscat的时候,他会进行检测空间大小是否能够满足拼接之后的字符串大小。如果不能,他会重新开辟一个拼接后的大度的二倍的字符串空间。
减少修改字符串时带来的内存重分配次数
C语言中,使用strcat的时候,用户需要手动开辟空间,然后使用函数进行字符串的拼接。频繁的申请空间是一个耗时的操作。但是Redis是一个数据库,很可能会有频繁的改变数据的操作,所以Redis不能容忍这种问题的出现,于是SDS的结构体中,哟一个free的属性,这个是用来记录未使用的空间的,实现了空间的预分配和惰性空间释放两种优化策略。
空间预分配
当使用SDS的一个API的时候,程序不仅会开辟足够容纳数据的空间,还会额外的开辟未使用的空间。
额外的未使用的空间的开辟,由如下的方式进行决定:
如果程序需要使用的SDS的len长度小于1M的话,程序会开辟和len长度一样大小的free空间。
如果修改之后的len长度大于1M的话,程序会分配free为1M的空间。
另外上面的两种方式还会多分配一个自己的空间,用于存放’\0’。
补充一点:只要当需要扩充内存空间的时候,才需要开辟。惰性空间释放
当SDS需要使用API去释放空间的时候,这个时候原有字符串会修改,但是开辟的空间并没有释放掉,而是将字符串向前移动,用free记录未使用的空间大小。
二进制安全
SDS底层通过二进制的方式来保存数据。
Redis不仅可以保存文本数据,还可以保存二进制数据。
即使是文本数据,也是转化成二进制数据保存的。
兼容部分C字符串函数
虽然是通过二进制保存数据,但是为了能够兼容string的使用,保存了字符串的一些特性。
SDS API
SDS主要的API如下表
函数 | 作用 | 时间复杂度 |
---|---|---|
sdsnew | 创建一个包含C字符串的SDS | O(N),N为给定的字符串的长度 |
sdsempty | 创建一个不包含任何内容的空SDS | O(1) |
sdsfree | 释放给定的SDS | O(N),N为被释放的SDS的长度 |
sdslen | 返回SDS的已经使用空间字节数 | O(1),通过读取对象的len值直接获取 |
sdsavail | 返回SDS未使用的空间字节数 | O(1),通过读取对象的free的值获取 |
sdsdup | 创建一个SDS的副本 | O,N是给定的SDS的长度 |
stdclear | 清空SDS保存的字符串内容 | O(1),由于惰性空间释放,只改变了对象的len值 |
stscat | 将给定C字符串拼接都SDS字符串的末尾 | O(N),N为被拼接的字符串的长度 |
sdscatsds | 将给定的SDS拼接到另一个SDS字符串的末尾 | O,N为被拼接的SDS字符串的长度 |
sdscpy | 将给定的C字符串复制到SDS里面,覆盖原有的字符串 | O(N),N为被复制的C字符串的长度 |
sdsgrowzero | 用空字符串将SDS扩展到给定长度 | O(N),N为扩展新增的字节数 |
sdssrange | 保留SDS给定区间的数据,不再全进的数据会被覆盖或者是清除 | O(N),N为被保留数据的字节数 |
sdstrin | 接受一个SDS和一个C字符串作为参数,从SDS左右两端移除所有在C字符串中出现过的字符串 | O(M*N),M为SDS的长度,N为给定C字符串的长度 |
sdscmp | 对比两个SDS字符串是否相同 | O(N),N为两个SDS中较短的那个SDS的长度 |
redis学习 -- 简单动态字符串相关推荐
- Redis之简单动态字符串sds
转载:https://segmentfault.com/a/1190000012262739 redis在处理字符串的时候没有直接使用以'\0'结尾的C语言字符串,而是封装了一下C语言字符串并命名为s ...
- Redis数据结构——简单动态字符串-SDS
1.SDS简介: redis没有使用C语言传统的字符串表示(以空字符结尾的字符数组),而是自己构建了一种名为简单动态字符串(SDS)的抽象类型,并将SDS用作redis的默认字符串表示. 除了用来保存 ...
- Redis数据结构——简单动态字符串
1.简单动态字符串 redis没有直接用C语言传统的字符串(以空字符结尾的字符数组)表示,而是自己构建了一种名为简单动态字符串(SDS)的抽象类型,并将SDS用作redis的默认字符串表示. 在red ...
- Redis内部数据结构详解之简单动态字符串(sds)
本文所引用的源码全部来自Redis2.8.2版本. Redis中简单动态字符串sds数据结构与API相关文件是:sds.h, sds.c. 转载请注明,本文出自:http://blog.csdn.ne ...
- Redis源码初探(1)简单动态字符串SDS
前言 现在面试可太卷了,Redis基本是必问的知识点,为了在秋招中卷过其他人(虽然我未必参加秋招),本菜鸡决定从源码层面再次学习Redis,不过鉴于本菜鸡水平有限,且没有c语言基础,本文不会对源码过于 ...
- redis源码学习-03_动态字符串SDS
概述 简单动态字符串(SDS, Simple Dynamic String)是 Redis 底层所使用的的字符串表示(而不是使用传统的 C 字符串). redis需要的不仅仅是一个字符串变量,而是一个 ...
- 【Redis系列2】Redis字符串对象之SDS(简单动态字符串)实现原理分析
Redis字符串对象之SDS实现原理分析 前言 字符串对象 为什么Redis的字符串对象是二进制安全的 SDS空间分配策略 空间预分配 惰性空间释放 SDS和C语言字符串区别 SDS的底层存储对象 d ...
- 《Redis设计与实现》阅读笔记(二)--简单动态字符串
简单动态字符串 Redis只在一些无需对字符串进行修改的地方使用C字符串,大部分时候使用简单动态字符串(simple dynamic string, SDS),字符串的抽象类型.二进制安全,可以存放任 ...
- Redis简单动态字符串
简单动态字符串 Simple Dynamic String是Redis内部自己定义的一种数据类型 在Redis内部, 任何包含字符串的键值对都是由SDS实现的 SDS还被用于缓冲区, 比如AOF缓冲区 ...
最新文章
- 在阿里云Kubernetes容器服务上打造TensorFlow实验室
- nginx 将请求全部指向到一个页面
- 我又来定计划了~2015-8至年底
- matlab gui打开fig文件,求助gui打开word文件及打开fig格式图片
- 2014年acm亚洲区域赛·鞍山站
- Linux设备驱动模型4——平台总线实践
- js中元素(图片)切换和隐藏显示问题
- UI素材|让设计有愉悦的体验,app交互动效的重要性!
- vim配置c语言开发环境变量,gcc配置和vim编程
- Jupyter更改主题和字体及远程访问
- 既然现在处理器性能过剩,为什么PC用起来不流畅?
- 微信公众号、小程序项目开发模板源码
- 4K标准---电视显示标准(ITU-R BT.2020)
- html动态生成表格源码,JavaScript动态生成表格的示例
- 搞写商业计划书的要点
- 数据时代建设医疗数据,主要有哪些意义?
- 微云php解析源码,微云网盘外链php源码 - 兼容并蓄 - 零零星星 - php - 外链 - 微云 - 源码 - HHTjim'S 部落格...
- php幸运大抽奖,幸运大转盘-jQuery+PHP实现的抽奖程序-完善中
- 【Excel】引用人民银行同期贷款利率(基准利率)和LPR利率的利息计算器(多项目)
- 肖像转素描:AI小素的前世今生
热门文章
- MongoDB(一):安装
- 导入drupal中文语言包
- mysql 去重con_python 爬虫 实现增量去重和定时爬取实例
- kmp求前缀和后缀的最大重复部分
- java多线程w3c_Java创建多线程的三种方式
- Java快速创建大量对象_3分钟 快速理解JVM创建对象的步骤!
- 微型计算机有什么电路组成,第二章 微型计算机的基本电路组成
- linux 内核调试信息在哪里,Linux kernel debug技巧----开启DEBUG选项
- Python OpenCV分水岭算法分割和提取重叠或有衔接的图像中的对象
- SIFT和SURF的替换算法——ORB (Oriented FAST and Rotated BRIEF 快速定向和旋转)