Redis设计与实现读书笔记(二) 链表
链表作为最基础的数据结构,在许多高级语言上已经有了很好的实现。由于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设计与实现读书笔记(二) 链表的更多相关文章
- Redis设计与实现读书笔记——双链表
前言 首先,贴一下参考链接: http://www.redisbook.com/en/latest/internal-datastruct/adlist.html, 另外真赞文章的作者,一个90后的小 ...
- Redis设计与实现读书笔记——简单动态字符串
前言 项目里用到了redis数据结构,不想只是简单的调用api,这里对我的读书笔记做一下记录.原文地址: http://www.redisbook.com/en/latest/internal-dat ...
- Redis设计与实现读书笔记(一) SDS
作为redis最基础的底层数据结构之一,SDS提供了许多C风格字符串所不具备的功能,为之后redis内存管理提供了许多方便.它们分别是: 二进制安全 减少字符串长度获取时间复杂度 杜绝字符串溢出 减少 ...
- Redis 设计与实现读书笔记一 Redis字符串
1 Redis 是C语言实现的 2 C字符串是 /0 结束的字符数组 3 Redis具体的动态字符串实现 /* * 保存字符串对象的结构 */ struct sdshdr { // buf 中已占用空 ...
- <<redis设计和实现>>读书笔记
redis如何实现主从同步的高效率?? 主从复制的同步有一个命令数据的同步文本,然后利用两个不同服务器的偏移量来进行进行同步,避免每次都是全部同步(并非会保存所有的命令数据,而是会有一个缓冲区(比如1 ...
- Redis 设计与实现读书笔记一 Redis List
list结构体 adlist.h/list(源码位置) /* * 双端链表结构 */ typedef struct list { // 表头节点 listNode *head; // 表尾节点 lis ...
- Linux内核设计与实现 读书笔记 转
Linux内核设计与实现 读书笔记: http://www.cnblogs.com/wang_yb/tag/linux-kernel/ <深入理解LINUX内存管理> http://bl ...
- 【2018.08.13 C与C++基础】C++语言的设计与演化读书笔记
先占坑 老实说看这本书的时候,有很多地方都很迷糊,但却说不清楚问题到底在哪里,只能和Effective C++联系起来,更深层次的东西就想不到了. 链接: https://blog.csdn.net/ ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
随机推荐
- spring/spring boot/spring cloud开发总结
背景 针对RPC远程调用,都在使用dubbo.dubbox等,我们也是如此.由于社区暂停维护.应对未来发展,我们准备尝试新技术(或许这时候也不算什么新技术了吧),选择使用了spring ...
- ActiveMQ(li)
一.ActiveMQ 首先,ActiveMQ不是一个框架,它不是struct,webx,netty这种框架,它更像是tomcat服务器,因为你使用它之前必须启动它,activeMQ和JMS的关系有点类 ...
- window环境下将solr6.3部署到tomcat中
1.我下载的solr是6.3版本的,需要jdk1.8及以上,tomcat8 JDK1.8的下载地址:http://www.Oracle.com/technetwork/Java/javase/down ...
- ASP.NET中后台数据和前台控件的绑定
关于ASP.NET中后台数据库和前台的数据控件的绑定问题 最近一直在学习个知识点,自己创建了SQL Server数据库表,想在ASP.NET中连接数据库,并把数据库中的数据显示在前台,注意,这里的数据 ...
- python语言中的编码问题
在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...
- [deviceone开发]-底部弹出选择
一.简介 个人上传的第一个示例源码,两天空闲时间写的,一点简单组件,写的挺乱还没啥注释,仅供新手学习. 底部弹出选择,可滑动选择选项,如果停留在选项中间,可自动校正位置,加了一点简单的动画效果,需要的 ...
- 错误:当你使用id作为sharepoint的自定义页面的查询参数时,总会提示项目不存在!
No item exists at http://SERVER/SITE/mypage.aspx?ID=1. It may have been deleted or renamed by anothe ...
- 【代码笔记】iOS-由身份证号码返回性别
一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. ...
- 【译】Spring 4 @PropertySource和@Value注解示例
前言 译文链接:http://websystique.com/spring/spring-propertysource-value-annotations-example/ 本篇文章将展示如何通过@P ...
- Unsupported major.minor version 51.0错误
错误原因:用jdk7编译的class文件放到基于jdk6运行在tomcat之中,就会报这个错 解决方法:项目------>右键------>属性------>Java Compile ...