简单动态字符串

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设计与实现》阅读笔记(二)--简单动态字符串的更多相关文章

  1. redis 学习笔记二 (简单动态字符串)

    redis的基本数据结构是动态数组 一.c语言动态数组 先看下一般的动态数组结构 struct MyData { int nLen; char data[0]; }; 这是个广泛使用的常见技巧,常用来 ...

  2. redis设计与实现(一)简单动态字符串

    redis是C语言实现的,但redis中的字符串并没有直接用C语言中的字符串表示,而是自己构建了一种简单的动态字符串类型(SDS). 在redis里面,C字符串只用作字面量,用在一些不会修改的地方,e ...

  3. redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表

    文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...

  4. Redis底层探秘(一):简单动态字符串(SDS)

    redis是我们使用非常多的一种缓存技术,他的性能极高,读的速度是110000次/s,写的速度是81000次/s.这么高的性能背后,到底是怎么样的实现在支撑,这个系列的文章,我们一起去看看. redi ...

  5. Redis数据类型之SDS简单动态字符串

    一,简单的动态字符串 1,Redis自己构建了一种名为简单动态字符串的抽象类型,并将SDS用作Redis的默认字符串表示, 2,在redis的数据库里面,包含字符串值的键值对在底层都是由SDS实现的 ...

  6. Redis设计与实现读书笔记——简单动态字符串

    前言 项目里用到了redis数据结构,不想只是简单的调用api,这里对我的读书笔记做一下记录.原文地址: http://www.redisbook.com/en/latest/internal-dat ...

  7. [redis读书笔记] 第一部分 数据结构与对象 简单动态字符串

    本读书笔记主要来自于<<redis设计与实现>> -- 黄键宏(huangz) redis主要设计了字符串,链表,字典,跳跃表,整数集合,压缩列表来做为基本的数据结构,实现键值 ...

  8. Html学习笔记(二) 简单标签

    标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...

  9. Redis5设计与源码分析读后感(二)简单动态字符串SDS

    一.引言 学习之前先了解几个概念: SDS定义:简单动态字符串,Redis的基本数据结构之一,用于储存字符串和整型数据. 二进制安全:C语言中用"\0"表示字符串结束,如果字符串本 ...

随机推荐

  1. 洛谷 P2045 方格取数加强版【费用流】

        题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...

  2. 经验总结13--EF配置

    EF配置,开发前的准备及步骤. 使用V22013和EF6.1. 1.使用VS新建MVC项目. 2.创建实体类. 3.配置web.config的数据库链接字符串. <connectionStrin ...

  3. 编译Console程序时,可以指定Main入口函数

    有如下简单的console程序 using System; namespace HelloWorld { class Program { static void Main(string[] args) ...

  4. 起床困难综合症 NOI_2014_D1T1

    这道题的正解其实没什么好说的,反而是部分分设计非常巧妙. 之所以要单开一篇是因为当时机房的部分同学刚学位运算,我拿这个题去讲想毒瘤大家一下,于是做了一个挺好看的课件. ppt -> pdf -& ...

  5. Python学习之路 (四)爬虫(三)HTTP和HTTPS

    HTTP和HTTPS HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法. HTTPS(Hypertext Transfer ...

  6. jQuery全选反选插件

    (function($){ $.fn.check = function(options){ var options = $.extend({ element : "input[name='n ...

  7. virtualbox+vagrant学习-2(command cli)-4-vagrant global-status命令

    Global Status 格式: vagrant global-status 这个命令将告诉你当前登录的用户系统上所有活跃的vagrant环境的状态. userdeMacBook-Pro:~ use ...

  8. 爬虫工具——Selenium和PhantomJS

    Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器上,它支持所有主流的浏 ...

  9. js检测是够断网

    方法 一 navigator.onLine   这个html5的 navigator的新特性可以很简单帮我们搞定 HTML5为此定义了一个navigator.onLine属性,这个属性值为true表示 ...

  10. nodejs 跨域设置cookie

    在做vue全家桶+express 做项目. 想做一个免登陆功能,选择session方案. 服务器设置session 后, 返回的响应头有Set-Cookie,但是浏览器的Application的coo ...