深入redis内部--实现双向链表
数据结构的应用--Adlist.h定义
1.节点结构
typedef struct listNode {
struct listNode *prev; //前向节点
struct listNode *next; //后向节点
void *value; //该节点的值
} listNode;
2.双向链表结构
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;
3.双向链表遍历器
typedef struct listIter {
listNode *next; //下一个节点
int direction;
} listIter;
方向定义
#define AL_START_HEAD 0 //向前查找
#define AL_START_TAIL 1 //向后查找
4.宏定义函数
#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)
#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))
#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)
5.定义函数
list *listCreate(void); //创建一个新的链表。该链表可以使用AlFree()方法释放。
//但使用AlFree()方法前需要释放用户释放私有节点的值。
//如果没有创建成功,返回null;创建成功则返回指向新链表的指针。
void listRelease(list *list); //释放整个链表,此函数不会执行失败。调用zfree(list *list)方法,定义在Zmalloc.c中。
list *listAddNodeHead(list *list, void *value); //向链表头部中增加一个节点
list *listAddNodeTail(list *list, void *value); //向链表尾部增加一个节点
list *listInsertNode(list *list, listNode *old_node, void *value, int after);//向某个节点位置插入节点 after为方向
void listDelNode(list *list, listNode *node);//从链表上删除特定节点,调用者释放特定私用节点的值。
//该函数不会执行失败
listIter *listGetIterator(list *list, int direction);//返回某个链表的迭代器。
//迭代器的listNext()方法会返回链表的下个节点。direction是方向
//该函数不会执行失败。
listNode *listNext(listIter *iter);
void listReleaseIterator(listIter *iter); //释放迭代器的内存。
list *listDup(list *orig); //复制整个链表。当内存溢出时返回null,成功时返回原链表的一个备份
//不管该方法是否执行成功,原链表不会改变。
listNode *listSearchKey(list *list, void *key); //从特定的链表查找key。成功则返回第一个匹配节点的指针
//如果没有匹配,则返回null。
listNode *listIndex(list *list, long index); //序号从0开始,链表的头的索引为0.1为头节点的下个节点。一次类推。
//负整数用来表示从尾部开始计数。-1表示最后一个节点,-2倒数第二个节点
//如果超过链表的索引,则返回null
void listRewind(list *list, listIter *li) {
li->next = list->head;
li->direction = AL_START_HEAD;
}
void listRewindTail(list *list, listIter *li) {
li->next = list->tail;
li->direction = AL_START_TAIL;
}
void listRotate(list *list); //旋转链表,移除尾节点并插入头部。
深入redis内部--实现双向链表的更多相关文章
- 关于redis内部的数据结构
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- redis内部数据结构深入浅出
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- 探索Redis设计与实现6:Redis内部数据结构详解——skiplist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现5:Redis内部数据结构详解——quicklist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现4:Redis内部数据结构详解——ziplist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 【转】Redis内部数据结构详解——ziplist
本文是<Redis内部数据结构详解>系列的第四篇.在本文中,我们首先介绍一个新的Redis内部数据结构--ziplist,然后在文章后半部分我们会讨论一下在robj, dict和zipli ...
- 【转】Redis内部数据结构详解 -- skiplist
本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...
- redisbook笔记——redis内部数据结构
在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 S ...
- [转]Redis内部数据结构详解-sds
本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...
随机推荐
- [Erlang28]使用匿名函数灵活组合不同的case
cowboy_http.erl里面的date1/2 启示: 以前一般写case里都是这样子: date1(Date) -> case month1(Date) of {error,badarg} ...
- C#语言各个版本特性(三)
三.查询集合 1.找出List<Product>列表中符合特定条件的所有元素 C#1.1 查询步骤:循环,if判断,打印 product类 using System.Collections ...
- DataGridView添加一行数据、全选、取消全选、清空数据、删除选中行
.net 2005下的Windows Form Application,一个DataGridView控件和4个Button,界面设置如下: 代码如下,有注解,相信大家都看得明白: ...
- Kafka与.net core(二)zookeeper
1.zookeeper简单介绍 1.1作用 zookeeper的作用是存储kafka的服务器信息,topic信息,和cunsumer信息.如下图: 而zookeeper是个什么东西呢?简单来说就是一个 ...
- @JoinColumn 详解
1. 一对一 现假设有Person表和Address表,是一对一的关系,在Person中有一个指向Address表主键的字段addressID,所以主控方一定是Person,所谓主控方就是能改变关联关 ...
- docker 存储驱动之 overlay2
overlay2 简介 OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 1) 更简单地设计 2) 从3.18开始,就进入了Linux内核主线 3) ...
- 开源NFV管理器 - OpenStack Tacker介绍 NFV和Tacker介绍和主要功能
原文链接:https://blog.csdn.net/bc_vnetwork/article/details/51463518 1.NFV概述 NFV(网络功能虚拟化Network Function ...
- django系列4.1--模版系统,过滤器,标签,模版继承,组件
django 模版系统 一. 语法 { { 变量 } } {% 表达式 %} 二. 变量 { {变量名} } 深度查询据点符( . )在模版语言中有特殊的含义. 当模版系统遇到点(.) 查询顺序如下: ...
- SoundPool在使用
Button playButton; SoundPool sp; int soundID_1,soundID_2; int streamID_1,streamID_2; @Override prot ...
- 基于scrapy-redis两种形式的分布式爬虫
redis分布式部署 1.scrapy框架是否可以自己实现分布式? - 不可以.原因有二. 其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...