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的长度 |
相关文章:
【stanford C++】容器III——Vector类
主要介绍如下5个容器类——Vector, Stack,Queue,Map和Set,各个都表示一重要的抽象数据类型。另外,各个类都是一些简单类型的值的集合,所以称它们为容器类。 暂且我们先不需要知道它们是如何实现的ÿ…

linux编译安装mysql 5.1_linux编译安装mysql5.1.x
安装mysql,安装前准备如果mysql用户不存在,那么添加mysql用户groupadd mysqluseradd -g mysql mysqlmysql编译安装make时间特别长wget http://downloads.mysql.com/archives/mysql-5.1/mysql-5.1.70.tar.gztar -zxvf mysql-5.1.70.tar.gzcd mysql-5.1.70…

Windows PowerShell 批量迁移Windows用户信息
这里说一下我在服务器上本地用户帐号、组的迁移 这里用到的迁移工具是 Windows PowerShell 迁移支持虚拟机和实体机器的迁移,虚拟机和虚拟机的迁移 但是不支持不同语种之间的迁移,比如英语向中文迁移 这里我实验的是虚拟机和虚拟机的迁移 系统是Windows…

css中position的几个值
1. staitic:该值符合文档的初始排版,其中设置的与位置有关的值不起作用。2.relative 该值的偏移量,是在文档初始排版的基础上进行排版,并且覆盖顺序是最新输出的在最上面3.absolute该值元素的定位是以网页文档左上角位基准,并且不…

一个较为详细的ETL系统实现方案
转至:http://www.cognoschina.net/club/viewthread.php?tid5627 1 ETL流程及调度设计(ETL Schedule)(PSP)1. ETL调度的目标快速见效系统要抽取39家分行四个系统的数据进行加工处理,数据从下传文件到ODS库,ODS库到LDM&…

python与anaconda区别_anaconda和python的区别是什么?
anaconda和python的区别是什么?Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。使用python需要下载安装执行python代码的环境。官方的Python包含了核心的模块和库,为了完成其他任务,需要安装其他的模块和库。Anaconda 是Py…

opencv 1 图像载入、显示和输出
三个函数 imread() namedWindow() inshow()1. imread 函数原型: Mat imread(const string& filename, int flags 1 );参数解析: const string& finename 将要载入的图片路径名。 Windows操作系统下面支持如下类型的图片: Window…

英文申请书范例
Dear Sir or Madam, I am applying for the position of Executive Assistant as advertised in the Recruitment Daily last evening. 我来应聘昨天晚上在每日招聘上发布的行政助理一职。 I have over five years of experience within this role during which time I have de…

c++ ofstream使用方法
ofstream是从内存到硬盘,ifstream是从硬盘到内存,流缓冲即是内存空间。 插入器<< : 向流输出数据。 cout << "test!" << endl; 将字符串输出到标准输出流。 析取器>> : 从流中输入数据 cin >> x; 从标准输入流…

JAVA 继承内存模型_Java内存模型
JVM的组成类加载器(classloader)执行引擎(execution engine)运行时数据区域(runtime data area)对于Java程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C程序开发程序员这样为内一个new 操作去写对应的delete/free操作,不容易出现内存泄…

Error: The INF file contains Unicode characters that could not be converted correctly
昨天第一次为自己的windows mobile程序制作CAB安装包,但是在生成过程中,却出现了这样一个问题:编译完成 -- 0 个错误,0 个警告time -> G:\WindowsMobile\time\time\bin\Debug\time.exe------ 正在启动项目“SmartDeviceCab1”的…

嵌入式开发板设置无密码登录
本次配置需要修改的ssh登录的配置文件 vi /etc/ssh/sshd_config允许root用户远程登录 设置PermitRootLogin参数值为yes #LoginGraceTime 2m PermitRootLogin yes #StrictModes yes #MaxAuthTries 6 #MaxSessions 10允许无密码登录 设置PermitEmptyPasswords 参数值修改为ye…

2012/08/27 夜
杂记于2012/08/27 唉,,最近公司在搬家,一直没有时间来看技术方面的资料,丫的上个星期天还接到第二天凌晨3点钟呢。。。唉。。有点受不了啊。。这苦逼的运维工作,,,呵,来说说这其中让…

存储过程和函数 PROCEDURE FUNCTION
SQL语句执行的时候,要首先编译,然后在被执行。在大型数据库系统中,为了提高效率,将为了完成特定功能的SQL语句集进行编译优化后,存储在数据库服务器中,用户通过指定存储过程的名字来调用执行。 具体而言&am…
Android——学习:线性布局权重分配
LinearLayout在Android中被广泛使用,LinearLayout有一个比较重要的属性——android:layout_weight。按照字面理解就是该控件的权重,这个值默认是 零(0)。 举个例子: 在下图中,整个界面是一个Linearlayout&a…

java bean配置文件_Spring中多配置文件及引用其他bean的方式
Spring多配置文件有什么好处?按照目的、功能去拆分配置文件,可以提高配置文件的可读性与维护性,如将配置事务管理、数据源等少改动的配置与配置bean单独分开。Spring读取配置文件的几种方式:1、使用Spring自身提供的ApplicationCo…

putty 串口登录开发板
安装putty 多个平台均可以安装putty pc端配置 使用串口线连接开发板 ls /dev 查看是否出现类似于ttyUSBx的文件 sudo putty 弹出页面,选择Serial Serial line填写/dev/ttyUSBx Speed填写115200(根据不同开发板,选择不同参数) 依次点击Load࿰…

win7下解决Android SDK Manger慢
2019独角兽企业重金招聘Python工程师标准>>> 今天准备做个Android小程序,以前配置的环境太久了,于是想配最新,但是花了大半天的时间遇到各种问题,最终还是配置好了。 1、首先修改C:\Windows\System32\drivers\etc\host…

Linux 工具进阶
参考网址 https://linuxtools-rst.readthedocs.io/zh_CN/latest/advance/index.html 转载于:https://www.cnblogs.com/artesian0526/p/9712258.html

ASP.NET MVC:利用ASP.NET MVC4的IBundleTransform集成LESS
背景 LESS确实不错,只是每次写完LESS都要手工编译一下有点麻烦(VS插件一直没有安装好),昨天在官方看到了如何用IBundleTransform集成LESS,今天就记录一下。 参考资料:http://www.asp.net/mvc/tutorials/mvc…

java锁屏_JAVA设置桌面不锁屏设置
//下面是编译命令// javac -encoding utf-8 Main.javaimport javax.swing.*;import java.awt.*;import java.awt.event.*;public class Main extends WindowAdapter {JLabel label null;public Main() {JFrame jFrame new JFrame("保持打开就不会锁屏");Container …

网线直连开发板
pc 端配置 点击pc端无线链接图标编辑链接以太网编辑IPv4设置方法:与其他计算机共享根据putty获取的动态ip使用ssh登录 解决 ip 无法登录问题 设置 pc 端 ip 和开发板 ip 在同一个网段 比如开发板 ip 是 10.42.0.123 可以设置自己机器的 ip 为 10.42.0.11 sudo i…

linux系统中指定端口连接数限制
限制22端口只能有两个连接 [code] iptables -P INPUT DROP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT iptables -A INPUT -p tcp --dport 22 -j ACCEPT [/code] 在此…

PHP-错误处理
错误处理 一、错误的分类 1、语法错误: 程序没法运行,直接提示语法错误。 2、运行时错误: 只有程序运行到某行,或在某些特定的情形下运行才会发生的错误。 3、逻辑错误: 程序从头到尾运行都没有发生(并提示…

C语言的变量的内存分配
今晚看了人家写的一个关于C语言内存分配的帖子,发现真是自己想找的,于是乎就收藏了。。。 先看一下两段代码: char* toStr() {char *s "abcdefghijkl";return s; } int main() {cout << toStr() << endl;return 0; }…

java打包_java工程打包(方式一)
1、新建工程myprojectpackage cn.zj;public class TestMain {public static void main(String[] args) {System.out.println("Hello World!");}}2、右击Java工程选择Export—>选择JAR file—>Next3、选择要打包的文件,不需要的文件不必打包…

s32v 开发板安装 apex 驱动
安装驱动 首先要获取到 apex.ko 文件,这个应该是硬件厂商提供,执行下面命令安装 首先需要给 apex.so 文件加上可执行权限 insmod apex.ko查看是否安装成功 执行下面命令,查看是否安装成功,如果安装成功,执行的结果中…

android常见错误与问题
1. Unable to start activity ComponentInfo 原因有很多种,我碰到一种: 可能是当前Activity里引用的View,并不存在于绑定的Layout里,而是在其他的Layout里,在Copy代码的时候,常会发生这种问题。

链式前向星(模板)
一种非常厉害的存图的数据结构! 本质:模拟链表的操作,链式存储图。(2,3都可以模拟链表的操作,替代链表) (1)二维数组存图:Map[x][y],一维代表出发…

tar 打包问题
项目中使用到 tar 文件,同一个 tar 文件解压之后在压缩,在程序执行的时候不能使用了 原因是 tar 对文件名长度有限制,当文件名过程的时候,使用 --formatustar 进行压缩