链表作为最基础的数据结构,在许多高级语言上已经有了很好的实现。由于redis采用C语言编写,需要自己实现链表,于是redis在adlist.h定义了链表类型。作者对于这部分没什么好说,源码比较简单,如果这方面没有接触过的话,作者也耐心地推荐了几本书供参考。为了提高效率,这里的链表指的是双向链表,使得某一个元素访问它的前驱与后继的时间复杂度均为O(1)。

  

  不多说,进入正题,首先可以看到节点的数据结构的代码如下:

typedef struct listNode {
struct listNode *prev; //前驱节点
struct listNode *next; //后继节点
void *value; //值
} listNode;

  C语言没有泛型,但是链表又要存储各种类型的数据,所以这里使用了void指针。由于指针只在编译器级别进行检查,在指令级别是没有类型的,所以这里是OK的。这里的value*指向真正的值存储空间。

  按理说使用上面的结构已经可以实现一个简单的链表,redis为了更加简便的使用链表,使用list结构体对节点进行了封装。

typedef struct list {
listNode *head; //头结点
listNode *tail; //尾节点
void *(*dup)(void *ptr); //函数指针,用于拷贝节点
void (*free)(void *ptr); //函数指针,用于释放节点
int (*match)(void *ptr, void *key); //用于比较节点的大小
unsigned long len; //链表的长度
} list;

  使用C语言实现面向对象编程的关键是定义函数指针作为接口,在使用时进行实现,这里定义了三种方法指针,分别用于类型的拷贝(在链表拷贝时调用),类型的释放(在链表释放时调用),类型的比较(类似于C++的运算符重载,用于比较类似的大小),这里的链表定义的写法值得好好学习一下。

   使用以上结构,redis存储一个简单的链表示意图如下:

  这里可以看到,redis实现的是无环链表,因为首元素的前驱是NULL。这样设计的理由是list已经持有了首元素和尾元素的指针,无需另外在首尾之间组成回路。这张图已经很明显的展示了链表的工作状态,下面对链表的操作的讨论仅以链表插入为例子来进行分析:

list *listAddNodeTail(list *list, void *value)
{
listNode *node; //定义保存值的节点 if ((node = zmalloc(sizeof(*node))) == NULL) //为这个新的节点进行分配空间
return NULL;
node->value = value;
if (list->len == ) { //链表为空的时候
list->head = list->tail = node;
node->prev = node->next = NULL;
} else {
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->len++;
return list;
}

  进行插入的过程比较容易,先定义出节点元素,然后根据链表的当前节点数进行不同的操作:当链表为空时,将list对应域指向node,而当链表不为空时,先完成新节点的成员赋值,然后再更改list的tail域等等,这里一定要注意的是双向列表的节点改变,要留心prev与next的值是否改变,而且新旧节点改变的顺序一定不能错,这个虽然简单,但是还是比较考验基本功的。

  总结:可以看出,一些知名的软件,底层还是最基础的东西,并没有什么黑科技,所以掌握好基础真的很重要。作者对这一章描述的比较简单,也就没什么好讲的了。希望以后可以继续坚持写博客。

Redis设计与实现读书笔记(二) 链表的更多相关文章

  1. Redis设计与实现读书笔记——双链表

    前言 首先,贴一下参考链接: http://www.redisbook.com/en/latest/internal-datastruct/adlist.html, 另外真赞文章的作者,一个90后的小 ...

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

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

  3. Redis设计与实现读书笔记(一) SDS

    作为redis最基础的底层数据结构之一,SDS提供了许多C风格字符串所不具备的功能,为之后redis内存管理提供了许多方便.它们分别是: 二进制安全 减少字符串长度获取时间复杂度 杜绝字符串溢出 减少 ...

  4. Redis 设计与实现读书笔记一 Redis字符串

    1 Redis 是C语言实现的 2 C字符串是 /0 结束的字符数组 3 Redis具体的动态字符串实现 /* * 保存字符串对象的结构 */ struct sdshdr { // buf 中已占用空 ...

  5. <<redis设计和实现>>读书笔记

    redis如何实现主从同步的高效率?? 主从复制的同步有一个命令数据的同步文本,然后利用两个不同服务器的偏移量来进行进行同步,避免每次都是全部同步(并非会保存所有的命令数据,而是会有一个缓冲区(比如1 ...

  6. Redis 设计与实现读书笔记一 Redis List

    list结构体 adlist.h/list(源码位置) /* * 双端链表结构 */ typedef struct list { // 表头节点 listNode *head; // 表尾节点 lis ...

  7. Linux内核设计与实现 读书笔记 转

    Linux内核设计与实现  读书笔记: http://www.cnblogs.com/wang_yb/tag/linux-kernel/ <深入理解LINUX内存管理> http://bl ...

  8. 【2018.08.13 C与C++基础】C++语言的设计与演化读书笔记

    先占坑 老实说看这本书的时候,有很多地方都很迷糊,但却说不清楚问题到底在哪里,只能和Effective C++联系起来,更深层次的东西就想不到了. 链接: https://blog.csdn.net/ ...

  9. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

随机推荐

  1. powerdesigner显示列描述信息

    将Comment中的字符COPY至Name中 -------------------------------------------------- Option   Explicit Validati ...

  2. sencha ext js 6 入门

    Sencha Ext JS号称是目前世界上最先进和最强大的.支持多平台多设备的JavaScript应用程序开发框架.首先看一下Ext JS的发展简史. 1 Ext JS发展简史 YUI-Ext的作者J ...

  3. 如何用CSS画三角形

    很多时候页面都需要一个或者多个小型三角形!多数人直接用PS扣个图片预览 下面用CSS简单画几个最终效果如下图 <div class="border-all-color"> ...

  4. SQL通过ContentTypeID找使用了内容类型的列表库

    DECLARE) SET @ContentTypeID='0x1B452DB25E92A34DA3E35FC8731278D2' SELECT w.Title AS [Web Site], w.Ful ...

  5. 解决NSTimer存在的内存泄漏的问题

    创建定时器会在一定的间隔后执行某些操作,一般大家会这样创建定时器,这样创建的定时,self对定时器有个引用,定时器对self也有个引用,造成了循环引用,最终造成了内存泄漏,如果定时器在做下载的操作就会 ...

  6. android 自定义控件——(三)水平线、虚线

    ----------------------------------View虚线或者直线(源代码下有属性解释)--------------------------------------------- ...

  7. 细分java环境中的JDK、JVM、JRE

    细分java环境中的JDK.JVM.JRE 近来小看了下Android,扑面而来一堆概念JDK.JVM.JRE.SDK.NDK.ADT.缕了一下,其中JDK.JVM.JRE是java环境的东西,而SD ...

  8. iOS 如何使用Safari浏览器打开app

    1.首先在info.plist添加一个键值对,如下图 或 2.在appdelegate.m文件如下方法写代码 -(BOOL)application:(UIApplication*)app openUR ...

  9. Mac利用PD虚拟机安装Centos7

    一.PD虚拟机的安装1.Parallels Desktop ,简称PD,号称是Mac上最好用的虚拟机,具体的就在此不进行过多描述.下附Mac .app文件夹下载,下载后放入/Applications/ ...

  10. vs2013 git 使用总结

    一.参与别人已经建好的项目 方法1.打开VS2013,切换到“团队资源管理器”,点上方“主页”右侧的下拉三角,选择项目->连接到团队项目,然后选择“克隆”,填入Git的Remote Url和要克 ...