2.简单动态字符串

2.1 SDS的定义

SDS的结构体:

int len//记录buf数组中已使用字节的数列

int free;//记录buf数组中未使用字节的数列

char buf[];//字节数组,用于保存字符串

2.2 SDS与C字符串的区别

2.2.1 常数复杂度获取字符串的长度:

C语言字符串获取长度时间复杂度为O(n)

2.2.2 杜绝缓冲区溢出

C字符串不记录自身长度,会造成缓冲区溢出

在对SDS进行修改时,API会检查SDS对空间是否满足修改所需对有求,如果不满足,API会自动将SDS的空间扩展至执行修改所需的大小,然后才执行所需的修改操作

2.2.3 减少修改字符串时带来的内存重分配次数

1.空间预分配

用于优化SDS字符串增长操作:当一个API对SDS进行修改,并且需要对SDS对空间进行扩展的时候,程序不仅会为SDS分配修改所必须要的空间,还会为SDS分配额外的未使用空间

当SDS的长度小于1MB,程序分配和len属性同样大小的未使用空间

当SDS的长度大于等于1MB,程序会分配1MB的未使用空间。

2.惰性空间释放

用于优化SDS字符串缩短操作:当SDS的API需要缩短SDS保存的字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用free属性将这些字节的数量记录起来,并等待将来使用。

2.2.4 二进制安全

C字符串只能存储文本数据

Redis不是使用buf来保存字符,而是用它来保存一系列二进制数据

2.2.5 兼容部分C字符串函数

可以重用一部分库定义的函数

3.链表

链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度

链表键、发布与订阅、慢查询、监视器等功能也用到来链表

3.1 链表和链表节点的实现

listnode{

listnode *head;

listNode *tail;

unsigned long len;

void *(*dup)(void *ptr);

void (*free)(void *ptr);

int (*match)(void *ptr, void *key);

}

Redis链表实现特性:

双端:prev指针,获取当前节点的前置节点,next指针,用来获取当前节点的后置节点

无环:表头节点的prev指针和next指针都指向NULL,对链表的访问以NULL为终点

带有表头节点和表尾节点指针:通过list的head指针和tail指针,程序获取链表的表头节点和表尾节点的复杂度为O(1)

带链表长度计数器:程序使用list结构的len属性来对list持有的链表节点进行计数,程序获取链表长度的时间复杂度为O(1)

多态:链表节点使用void*指针来保存节点值,可以通过dup,free,match为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站...
    Java架构阅读 1,299评论 1 16
  • 转载:可能是目前最详细的Redis内存模型及应用解读 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据...
    meng_philip123阅读 1,450评论 1 22
  • 人间从来都值得,不值得的,只有你我。两个月了,还是不能控制自己想你,我一直觉得自己是个足够冷漠的人,即使面对生死别...
    001lm阅读 238评论 0 0
  • 戏说水浒全目录 上回我们说到,那扈三娘正一边鞭挞着夫君矮脚虎、一边口中强调着“只是干妹妹”的时候,黑旋风李逵迈步走...
    这是文阅读 1,962评论 0 3
  • 第四章 玄幻门正是因为它的虚幻而得名,除了岛主黄芪外,无论谁进入后出来都会变成两个人,其中一真一假。只有黄芪才能辨...
    墨存啊阅读 301评论 0 1