iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >redis 5.0.7 源码阅读——双向链表
  • 380
分享到

redis 5.0.7 源码阅读——双向链表

redis5.0.7源码阅读——双向链表 2015-06-06 15:06:30 380人浏览 绘本
摘要

Redis中动态字符串sds相关的文件为:adlist.h与adlist.c 一、数据结构 redis里定义的双向链表,与普通双向链表大致相同 单个节点: 1 typedef struct listnode { 2 st

redis 5.0.7 源码阅读——双向链表

Redis中动态字符串sds相关的文件为:adlist.h与adlist.c

一、数据结构

redis里定义的双向链表,与普通双向链表大致相同

单个节点:

1 typedef struct listnode {
2     struct listNode *prev;
3     struct listNode *next;
4     void *value;
5 } listNode;

链表:

1 typedef struct list {
2     listNode *head;
3     listNode *tail;
4     void *(*dup)(void *ptr);
5     void (*free)(void *ptr);
6     int (*match)(void *ptr, void *key);
7     unsigned long len;
8 } list;

链表以函数指针的方式,实现了复制、销毁与比较的方法的多态。

迭代器:

1 typedef struct listIter {
2     listNode *next;
3     int direction;
4 } listIter;

迭代器中有个成员变量direction,用于表示当前遍历的方向。

大致结构:

 1                                             

二、创建

redis中创建一个初始双向链表比较简单,只要分配好内存,并给成员变量赋初值就可以了

 1 list *listCreate(void)
 2 {
 3     struct list *list;
 4 
 5     if ((list = zmalloc(sizeof(*list))) == NULL)
 6         return NULL;
 7     list->head = list->tail = NULL;
 8     list->len = 0;
 9     list->dup = NULL;
10     list->free = NULL;
11     list->match = NULL;
12     return list;
13 }

 

redis中提供了头插法、尾插法以及指定位置插入节点三种方式向链表中添加节点,与普通双向链表无异,此处不做详细叙述。

三、销毁

因链表中每个节点的value可能指向堆空间,故不能直接把list结构体free,这样会造成内存泄露。需要先将每个节点的value释放,才可以free结构体

清空所有节点:

 1 void listEmpty(list *list)
 2 {
 3     unsigned long len;
 4     listNode *current, *next;
 5 
 6     current = list->head;
 7     len = list->len;
 8     while(len--) {
 9         next = current->next;
10         //若指定了销毁的函数,则使用指定的函数进行销毁value
11         if (list->free) list->free(current->value);
12         zfree(current);
13         current = next;
14     }
15     list->head = list->tail = NULL;
16     list->len = 0;
17 }

销毁链表:

1 void listRelease(list *list)
2 {
3     listEmpty(list);
4     zfree(list);
5 }

同样,redis的链表提供了与普通链表相同的删除单个节点的操作,此处也不做叙述。

四、迭代器操作

redis中提供了获取迭代器的接口

 1 listIter *listGetIterator(list *list, int direction)
 2 {
 3     listIter *iter;
 4 
 5     if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
 6     if (direction == AL_START_HEAD)
 7         iter->next = list->head;
 8     else
 9         iter->next = list->tail;
10     iter->direction = direction;
11     return iter;
12 }

以AL_START_HEAD为例,生成好的迭代器结构如下:

 

 1                                                                                 

迭代器的next方法:

 1 listNode *listNext(listIter *iter)
 2 {
 3     listNode *current = iter->next;
 4 
 5     if (current != NULL) {
 6         if (iter->direction == AL_START_HEAD)
 7             iter->next = current->next;
 8         else
 9             iter->next = current->prev;
10     }
11     return current;
12 }

调用一次之后的结构:

 1                                                                               

再次调用:

 1                                                                             

调用next函数的返回值为调用之前的listNode首地址

五、其它操作

redis的双向链表还提供了其它操作。其中,查找指定的key与复制整个list依赖于迭代器的使用,并使用到自定义的比较/复制方法。

除此之外,还提供了类似随机读取的方式,其内部实现为遍历,且“越界”时返回NULL。同时,它支持index为负数,表示从尾开始。类似旋转的操作,把尾节点移至原头节点之前,成为新的头节点。当然,还有拼接两个链表的操作。

 

 

redis 5.0.7 下载链接

Http://download.redis.io/releases/redis-5.0.7.tar.gz

源码阅读顺序参考:

https://GitHub.com/huangz1990/blog/blob/master/diary/2014/how-to-read-redis-source-code.rst

您可能感兴趣的文档:

--结束END--

本文标题: redis 5.0.7 源码阅读——双向链表

本文链接: https://www.lsjlt.com/news/3853.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis源码阅读:Redis字符串SDS详解
    SDS 基本概念 简单动态字符串(Simple Dynamic String)SDS,用作Redis 的默认字符串。 C语言中的字符串:以空字符结尾的字符数组 SDS实现举例 r...
    99+
    2024-04-02
  • java代码实现双向链表
    本文实例为大家分享了双向链表java实现代码,供大家参考,具体内容如下 一、双向链表简介 1、单链表的缺陷 单链表只能从头结点开始访问链表中的数据元素,如果需要逆序访问单链表中的数据...
    99+
    2024-04-02
  • C++代码实现双向链表
    本文实例为大家分享了C++实现双向链表的具体代码,供大家参考,具体内容如下 双向链表:两个指针域,一个指向前结点,一个指向后结点 list.h #pragma once #defin...
    99+
    2024-04-02
  • C++实现双向链表代码分析
    目录前言:一、双向链表优缺点二、C++实现分析(1)节点类(2)链表类分析(3)链表类构造函数(4)isEmpty()判断是否为空(5)size()获取链表长度(6)getNode(...
    99+
    2024-04-02
  • Redis快速表、压缩表和双向链表(重点介绍quicklist)
    前言 最近在看《Redis的设计与实现》这本书,写的真的是太好了,一下子就看入迷了,谢谢作者。不过在学习的时候发现一个问题,我服务器上安装的是Redis5.0.9版本的,而作者介绍的...
    99+
    2024-04-02
  • C++双向链表的增删查改操作方法源码分析
    这篇“C++双向链表的增删查改操作方法源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++双向链表的增删查改操作方法...
    99+
    2023-07-05
  • 怎么用java代码实现双向链表
    这篇文章主要介绍“怎么用java代码实现双向链表”,在日常操作中,相信很多人在怎么用java代码实现双向链表问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用java代码实现双向链表”的疑惑有所帮助!接下来...
    99+
    2023-06-30
  • java双向循环链表的实现代码
    例1:复制代码 代码如下:package com.xlst.util; import java.util.HashMap;import java.util.Map;import ja...
    99+
    2022-11-15
    java 双向循环链表
  • 如何使用C++代码实现双向链表
    这篇文章主要介绍“如何使用C++代码实现双向链表”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用C++代码实现双向链表”文章能帮助大家解决问题。双向链表:两个指针域,一个指向前结点,一个指向后...
    99+
    2023-06-30
  • Redis中快速表、压缩表和双向链表的区别有哪些
    这篇文章主要介绍Redis中快速表、压缩表和双向链表的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言最近在看《Redis的设计与实现》这本书,写的真的是太好了,一下子就看入迷了,谢谢作者。不过在学习的时...
    99+
    2023-06-14
  • C语言带头双向循环链表的示例代码
    目录前言结构分析链表的基本操作实现创建节点初始化链表链表销毁打印链表链表尾插链表尾删链表头插链表头删链表查找链表pos位置前面去插入删除pos位置链表判空代码复用总代码及头文件前言 ...
    99+
    2022-11-13
    C语言带头双向循环链表 C语言 双向循环链表 C语言 循环链表
  • C++双向循环链表类模版实例代码分析
    本文小编为大家详细介绍“C++双向循环链表类模版实例代码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++双向循环链表类模版实例代码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.插入某个节点流程如...
    99+
    2023-06-29
  • JavaScript双向链表实现LRU缓存算法的示例代码
    目录目标什么是LRU简介硬件支持寄存器栈代码实现思路链表节点数据结构链表数据结构LRUCache数据结构完整代码测试目标 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束...
    99+
    2024-04-02
  • redis源码分析教程之压缩链表ziplist详解
    前言 压缩列表(ziplist)是由一系列特殊编码的内存块构成的列表,它对于Redis的数据存储优化有着非常重要的作用。这篇文章总结一下redis中使用非常多的一个数据结构压缩链表ziplist。该数据结构...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作