redis系列 二、链表原理

概述

除了字符串外,链表作为一种常用的数据结构,提供了高效的节点重排能力以及顺序性的节点访问。redis 使用的C语言没有内置链表结构,本篇博客我就来整理下 redis 链表类型的实现。


redis 数据类型

redis 有以下五种常用的数据类型:

  • String:字符串类型
  • Hash:哈希类型
  • List:链表类型
  • Set:集合类型
  • zSet:有序集合类型

1、List 链表类型

C语言默认是不支持链表的,redis 使用头文件 adlish.h 中的 ListNode 表示单个链表结构:

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

多个节点之间通过 prev 和 next 指针组成双端链表,具体结构如下所示:

仅仅使用 ListNode 是可以组成链表,但使用 adlish.h 的 List 来持有链表的话,操作会更高效:

typedef struct list {
    // 表头节点
    listNode * head;
    // 表尾节点
    listNode * tail;
    // 链表所包含的节点数量
    unsigned long len;
    // 节点值复制函数
    void *(*dup)(void *ptr);
    // 节点值释放函数
    void (*free)(void *ptr);
    // 节点值对比函数
    int (*match)(void *ptr,void *key);
} list;

list 结构为链表提供了表头、表尾、链表节点数以及三个不同类型的函数:

  • dup 函数用于复制链表节点所保存的值;
  • free 函数用于释放链表节点所保存的值;
  • match函数则用于对比链表节点所保存的值和另一个输入值是否相等

dup、free,match 是用于实现多态链表所需的类型特定函数。下面我们看一张 List 和 ListNode 合用的结构图:

总结一下,redis 链表结构的实现有以下特性:

  1. 双向链接,获取某个节点的前驱节点以及后记节点的时间复杂度都为O(1)
  2. 无环,head 的前驱节点以及 tail 的后继节点都为 NULL
  3. 访问链表头节点和链表尾节点的时间复杂度都为O(1)
  4. 访问链表长度的时间复杂度为O(1)
  5. 多态,链表节点使用 void* 指针来保存节点值,并可以通过 list 结构提供的 dup、free、match 三个属性为节点值设定特定类型函数,所以链表可以保存各种类型的值

链表常用 API

下面我通过表格的形式给出 redis 链表常用的函数方法:


链表用途

链表在 redis 中的用途非常广泛。除了在 列表键 中使用外,很多其他功能也用到了链表。

  • 链表键:当我们称一个键为列表键时,数据库中该键锁对应的值为链表类型

redis 的发布与订阅、慢查询、监视器等功能也用到了链表。redis 服务器本身还使用链表来保存多个客户端的状态信息,以及使用链表来构建客户缓冲区。


————————————————
版权声明:本文为CSDN博主「吃饭睡觉胖胖胖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/meiyongdesan/article/details/107153491

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值