由阿特拉斯 2018-1-3
<人力资源/>
1。SDS
-
<李>描述李>
复述,底层是C语言编写,而复述,没有直接使用C语言的字符串表示,是自己构建了一种名为简单动态字符串的抽象类型,即SDS(简单的动态字符串)。
引用>
复述,数据库里,包含字符串值的键值对在底层都是SDS实现的,可以说SDS是基石。
AOF模块中的AOF缓冲区,以及客户端状态中的输入缓冲区,都是SDS实现的。<李>定义李>
<代码> struct sdshdr {//记录buf数组中已使用字节的数量//等于SDS所保存字符串的长度 int len;//记录buf数组中未使用字节的数量 int免费;//字节数组,用于保存字符串 char buf []; }代码><李>结构李>
<李>免费属性值为0,表示这个SDS没有未使用空间。李> <李>兰属性值为5,表示这个SDS保存了一个5字节长的字符串。李> <李> buf属性是字符类型数组,数组前5个字节分别保存‘R’,‘e’,‘d’,‘我’,“s”5个字符,最后1个字节保存了空字符“\ 0”。李> <李> buf长度=len +免费+ 1。李>
引用><李>策略李>
<李> SDS遵循C字符串以空字符“\ 0”结尾的惯例好处是可以直接重用一部分C字符串函数。李> <李>较C字符串SDS在兰属性中记录了SDS本身的长度,从而获取SDS长度复杂度仅为O(1)。李> <李>较C字符串SDS读取字符不是通过结尾空字符“\ 0”而是兰属性因此更安全,使得复述,不仅可以保存文本数据,还可以保存任意格式的二进制数据。李> <李>较C字符串SDS的空间分配策略完全杜绝了发生缓冲区溢出的可能,检查免费属性是否满足修改需求,如果不满足,自动拓展空间然后再执行修改操作,如果空间足够,则无需执行内存重分配。李> <李>空间分配策略优化策略空间预分配和惰性空间释放减少了内存重分配次数。李> <李>空间预分配公式:
引用>
如果修改SDS后,SDS的len将小于1 mb,那么分配和len属性同样大小的自由空间;
如果修改SDS后,SDS的len将大于等于1 mb,那么分配1 mb的自由空间。李> <李>惰性空间释放策略即SDS空间修改操作释放多出来的空间保留,避免缩短字符串的内存重分配和提供将来有可能的字符串增长。李> <李> SDS提供了释放SDS空间的API,所以不必担心惰性空间释放会造成内存浪费。李>2。
列表<李>描述李>
链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度。
引用>
列表键的底层实现之一就是链表。
发布与订阅,慢查询,监视器等功能也用到了链表,复述,服务器本身还使用链表来保存多个客户端的状态信息,以及使用链表来构建客户端输出缓冲区。<李>定义李>
<代码> typeof struct listNode {//前置节点 struct listNode *:;//后置节点 struct listNode *下;//节点的值 void *值; }listNode; 代码><代码> typeof struct{列表//表头节点 listNode *头;//表尾节点 listNode *尾巴;//链表包含的节点数量 无符号长兰;//节点值复制函数 void * (* dup) (void * ptr);//节点值释放函数 空白(*免费)(void * ptr);//节点值对比函数 int(*匹配)(void * ptr, void *键); }列表;代码><李>结构李>
<李>策略李>
双端:链表节点带有上一页和下一页指针,获取某个节点的前置节点和后置节点的复杂度都是O (1)。
无环:表头节点页的上一页指针和表尾节点的下一指针都指向空,对链表的访问以零为终点。
带链表长度计数器:单结构的兰属性使得获取链表节点数量的复杂度是O (1)。
多态:链表节点使用void *指针来保存节点值,并且可以通过列表结构的复制品,免费的,属匹配性为节点设置类型特定函数,所以链表可以保存各种不同类型的值。复述,笔记——数据结构篇