《Redis设计与实现》阅读笔记(二)--简单动态字符串
简单动态字符串
Redis只在一些无需对字符串进行修改的地方使用C字符串,大部分时候使用简单动态字符串(simple dynamic string, SDS),字符串的抽象类型。二进制安全,可以存放任意格式的数据。
定义
源码(部分):
struct __attribute__ ((__packed__)) sdshdr5 {
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* used */
uint8_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
书中代码:
struct sdshdr {
int len;
int free;
char buf[];
}
这里以书中代码为基础,len为使用的字节数,free表示已分配但未使用的字节数。buf就是char型数组保存字符串。
这里需要注意的是SDS保存的字符串沿用C字符串的格式,会在最末尾加一个'\0'表示字符串结束,好处是可以复用C语言的函数库。
举个例子:“hello” len为5,如果free为0,那么这个字符串一共使用6字节,'\0'额外使用一个字节。
由定义我们可以了解到,SDS的长度可以O(1)获得,而且他使用的内存不是长度+1。而且具有二进制安全的性质。
空间分配策略
Redis为了减少内存分配的次数,采用了空间预分配和惰性空间释放两种策略。
空间预分配
当需要对SDS进行空间扩展的时候,SDS不仅会分配修改所必须的空间,还会进行预分配。
如果修改后的len值小于1M,那么就会预分配和len同样大小的预留空间。也就是说经过修改和预分配len和free的值是相等的。这时候占有的字节数就是len+free+1。
而如果修改后的len值大于等于1M,那么就只预分配1M空间。
惰性空间释放
当API需要缩短SDS保存的字符串,并不会立即释放多出来的字节,而是使用free记录下来。这样避免了内存重分配的操作,并为将来可能的增长提供了优化。
如果确实需要释放未使用的空间,SDS也提供了相应的API。
优点总结
- 常数时间复杂度获取字符串长度
- 杜绝缓冲区溢出
- 减少在修改字符串长度时内存分配的次数
- 二进制安全
- 兼容部分C字符串函数
《Redis设计与实现》阅读笔记(二)--简单动态字符串的更多相关文章
- redis 学习笔记二 (简单动态字符串)
redis的基本数据结构是动态数组 一.c语言动态数组 先看下一般的动态数组结构 struct MyData { int nLen; char data[0]; }; 这是个广泛使用的常见技巧,常用来 ...
- redis设计与实现(一)简单动态字符串
redis是C语言实现的,但redis中的字符串并没有直接用C语言中的字符串表示,而是自己构建了一种简单的动态字符串类型(SDS). 在redis里面,C字符串只用作字面量,用在一些不会修改的地方,e ...
- redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表
文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...
- Redis底层探秘(一):简单动态字符串(SDS)
redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...
- Redis数据类型之SDS简单动态字符串
一,简单的动态字符串 1,Redis自己构建了一种名为简单动态字符串的抽象类型,并将SDS用作Redis的默认字符串表示, 2,在redis的数据库里面,包含字符串值的键值对在底层都是由SDS实现的 ...
- Redis设计与实现读书笔记——简单动态字符串
前言 项目里用到了redis数据结构,不想只是简单的调用api,这里对我的读书笔记做一下记录.原文地址: http://www.redisbook.com/en/latest/internal-dat ...
- [redis读书笔记] 第一部分 数据结构与对象 简单动态字符串
本读书笔记主要来自于<<redis设计与实现>> -- 黄键宏(huangz) redis主要设计了字符串,链表,字典,跳跃表,整数集合,压缩列表来做为基本的数据结构,实现键值 ...
- Html学习笔记(二) 简单标签
标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...
- Redis5设计与源码分析读后感(二)简单动态字符串SDS
一.引言 学习之前先了解几个概念: SDS定义:简单动态字符串,Redis的基本数据结构之一,用于储存字符串和整型数据. 二进制安全:C语言中用"\0"表示字符串结束,如果字符串本 ...
随机推荐
- 洛谷 P2045 方格取数加强版【费用流】
题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...
- 经验总结13--EF配置
EF配置,开发前的准备及步骤. 使用V22013和EF6.1. 1.使用VS新建MVC项目. 2.创建实体类. 3.配置web.config的数据库链接字符串. <connectionStrin ...
- 编译Console程序时,可以指定Main入口函数
有如下简单的console程序 using System; namespace HelloWorld { class Program { static void Main(string[] args) ...
- 起床困难综合症 NOI_2014_D1T1
这道题的正解其实没什么好说的,反而是部分分设计非常巧妙. 之所以要单开一篇是因为当时机房的部分同学刚学位运算,我拿这个题去讲想毒瘤大家一下,于是做了一个挺好看的课件. ppt -> pdf -& ...
- Python学习之路 (四)爬虫(三)HTTP和HTTPS
HTTP和HTTPS HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法. HTTPS(Hypertext Transfer ...
- jQuery全选反选插件
(function($){ $.fn.check = function(options){ var options = $.extend({ element : "input[name='n ...
- virtualbox+vagrant学习-2(command cli)-4-vagrant global-status命令
Global Status 格式: vagrant global-status 这个命令将告诉你当前登录的用户系统上所有活跃的vagrant环境的状态. userdeMacBook-Pro:~ use ...
- 爬虫工具——Selenium和PhantomJS
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器上,它支持所有主流的浏 ...
- js检测是够断网
方法 一 navigator.onLine 这个html5的 navigator的新特性可以很简单帮我们搞定 HTML5为此定义了一个navigator.onLine属性,这个属性值为true表示 ...
- nodejs 跨域设置cookie
在做vue全家桶+express 做项目. 想做一个免登陆功能,选择session方案. 服务器设置session 后, 返回的响应头有Set-Cookie,但是浏览器的Application的coo ...