redis7.x源码分析:(2) adlist双向链表

链表是一种常用的数据结构(如果不了解,请先学习数据结构),由于c语言本身没有实现标准的链表库,所以redis自己实现了一个双向链表。

双向链表在redis内部的使用非常的多,几乎所有模块中都有用到。

下面看下它的结构定义:

cpp 复制代码
// 节点
typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

// 迭代器
typedef struct listIter {
    listNode *next;
    int direction;
} listIter;

// 双向链表
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;

listNode中的value定义为void *,所以它可以被用来存储任意类型的数据。而对于不同的数据,在处理时可能需要用到不同的函数,因此在list中定义了3个函数指针,分别对应不同类型数据的复制、释放和对比功能。当对value进行处理时,如果设置了函数指针,就有可能会调用它们进行相应处理。

比如在清空函数中:

cpp 复制代码
void listEmpty(list *list)
{
    unsigned long len;
    listNode *current, *next;

    current = list->head;
    len = list->len;
    while(len--) {
        next = current->next;
        // 释放
        if (list->free) list->free(current->value);
        zfree(current);
        current = next;
    }
    list->head = list->tail = NULL;
    list->len = 0;
}

当 free 函数指针不为空时,会调用它释放value。而 dup 和 match 函数会分别在 listDup 和 listSearchKey 中使用。由于双向链表整体代码实现比较简单,因此其它代码也不作过多说明。

最后我们再简单看下迭代器:

cpp 复制代码
// 迭代器
typedef struct listIter {
    listNode *next;
    int direction;
} listIter;

/* Directions for iterators */
#define AL_START_HEAD 0
#define AL_START_TAIL 1

它由一个节点指针和迭代方向组成

  • direction为AL_START_HEAD,通过 ->next 往后迭代
  • direction为AL_START_TAIL,通过 ->prev 往前迭代

迭代器的相关函数:

cpp 复制代码
// 创建迭代器
listIter *listGetIterator(list *list, int direction);
// 根据方向迭代
listNode *listNext(listIter *iter);
// 释放迭代器
void listReleaseIterator(listIter *iter);
// 重置迭代器到表头
void listRewind(list *list, listIter *li);
// 重置迭代器到表尾
void listRewindTail(list *list, listIter *li);
相关推荐
FoldWinCard4 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计5 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
她说可以呀5 小时前
Redis哨兵
数据库·redis·bootstrap
tedcloud1235 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质5 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX5 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.6 小时前
Linux系统管理
linux·运维
阿龙的工作记录6 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手6 小时前
Linux的基本指令
linux·运维·服务器
hkj88087 小时前
Ubuntu 切换java版本
java·linux·ubuntu