Redis数据结构—链表与字典的结构

大家好,我是白泽。今天我们来聊一聊Redis中的链表与字典的结构

链表

关于链表的基础概念其实你在学习Redis之前一定积累了不少,所以本文将默认你已经掌握了链表相关的基础知识,而Redis的链表其实也就是普通的链表~

因为Redis是使用C语言编写的,因此Redis的数据结构的定义都是使用C语法定义的,你不需要完全理解下方C语言声明结构体的语法,但我认为依靠大家的Java知识也能理解这就像是在Java中定义了一个链表对象

Redis链表节点的结构
typedef struct listNode {
struct listNode *prev; //指向前一个链表节点
struct listNode *next; //指向后一个链表节点
void *value; //当前节点的值(可以按需设定不同数据类型的value)
} listNode;

很明显,当每一个节点内记录了前后两个节点位置之后,链表节点之间就能够彼此前后相连,组成双向通行车道(可以双向遍历)

Redis链表的表示

上面讲解了Redis的链表的节点表示,并由此引申了一下可以借此构建Redis双端链表,而事实上,对于每一个存在的双端链表,Redis使用一个list结构来表示

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

很明显,你看到三个好像是返回值为void的函数,但是看不懂C语法,没关系,传统后端功夫,自然是点到为止

Redis链表用在哪

我不想现在就告诉你,链表被广泛用于实现Redis的各种功能,比如列表键、发布于订阅、慢查询、监视器等(这太空洞了,除了让你听一遍这几个词汇,对你没有任何帮助),等我们后面讲到这几部分的时候,白泽再结合链表和你细说~

字典

和链表一样,Redis所使用的C语言并没有内置字典这种数据结构,因此Redis构建了自己的字典实现。如果你学过数据结构,你会发现Redis的字典事实上就是数据结构中的邻接表,即使没学过,往下看就好啦~

Redis字典结构总览

数组 + 链表 ==> 邻接表,实锤

Redis字典结构分解

还记得吗,上面我们说Redis链表可以用list描述,但是链表存储的数据本质上,是由一系列listNode节点通过前后指针相连存储的;类似的,Redis字典可以用如下dict描述,但是字典存储的数据本质上,是由数组 + 若干链表组合得到的数据结构存储的,字典dict结构如下:

typedef struct dict {
dictType *type; //类型特定函数
void *privdata; //私有数据
dictht ht[2]; //哈希表数组
int trehashidx; //rehash索引,当rehash不在进行时,值为-1
} dict;

现在你只需要关注其中的哈希表数组ht[2],它的数据类型为dictht,因此也是一种复合的数据结构,如下:

typedef struct dictht {
dictEntry **table; //哈希表数组
unsigned long size; //哈希表大小
unsigned long sizemax; //哈希表大小掩码,用于计算索引值,等于size - 1
unsigned long used; //该哈希表已有节点的数量
} dictht;

哈希表dictht是Redis字典的核心,dictht的四个属性中,size、sizemax、used都是用于描述table属性整体状态。看到这你就明白了,dictht的核心是dictEntry类型的table属性(再次提醒,如果没有C语言的基础,本文中一切你看不懂的语法,包括数据类型,你只需要一眼带过即可,我们的目的是学习Redis的设计思想

table属性是一个数组,数组中的每个元素都是一个指向dictEntry结构的指针,每个dictEntry结构保存一个键值对,并含有一个指向下一个dictEntry的指针,结构如下:

typedef struct dictEntry {
void *key; //键
union { //值(可以是一个指针,可以是一个uint64_t类型的整数,也可以是一个int64_t类型的整数)
void *val;
uint64_t u64;
int64_t s64;
} v;
struct dictEntry *next;//指向下个哈希表节点,形成链表
} dictEntry;
Redis字典的使用

很抱歉,我不太想将一篇文章的篇幅变得太大,因为阅读大体量的技术文章确实容易令人心生退意,所以本文也点到为止。关于Redis字典的使用部分的知识将在白泽下一篇博客继续讲解,敬请期待~

Redis数据结构—链表与字典的结构的更多相关文章

  1. Redis数据结构—链表与字典

    目录 Redis数据结构-链表与字典 链表 Redis链表节点的结构 Redis链表的表示 Redis链表用在哪 字典 Redis字典结构总览 Redis字典结构分解 哈希算法 解决键冲突 rehas ...

  2. 第18章 Redis数据结构常用命令

    18-1 字符串的一些基本命令 18-1 :配置Spring关于Redis字符串的运行环境 <bean id="poolConfig" class="redis.c ...

  3. Redis数据结构——quicklist

    之前的文章我们曾总结到了Redis数据结构--链表和Redis数据结构--压缩列表这两种数据结构,他们是Redis List(列表)对象的底层实现方式.但是考虑到链表的附加空间相对太高,prev 和 ...

  4. redis 笔记01 简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表

    文中内容摘自<redis设计与实现> 简单动态字符串 1. Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS(Simple Dynamic String,简单动态 ...

  5. 深入理解Redis 数据结构—字典

    字典,又称为符号表.关联数组或映射,是一种用于保存键值对的抽象数据结构.在字典中,一个键可以和一个值进行关联,这些关联的键和值称为键值对.键值对中键是唯一的,我们可以根据键key通过映射查找或者更新对 ...

  6. 京东云开发者| Redis数据结构(二)-List、Hash、Set及Sorted Set的结构实现

    1 引言 之前介绍了Redis的数据存储及String类型的实现,接下来再来看下List.Hash.Set及Sorted Set的数据结构的实现. 2 List List类型通常被用作异步消息队列.文 ...

  7. Redis数据结构之字典

    Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对. 一.字典结构定义1. 哈希表节点结构定义: 2. 哈希表结构定义: 3. 字典 ...

  8. 深入理解Redis 数据结构—双链表

    在 Redis 数据类型中的列表list,对数据的添加和删除常用的命令有 lpush,rpush,lpop,rpop,其中 l 表示在左侧,r 表示在右侧,可以在左右两侧做添加和删除操作,说明这是一个 ...

  9. Redis数据结构详解(2)-redis中的字典dict

    前提知识 字典,又被称为符号表(symbol table)或映射(map),其实简单地可以理解为键值对key-value. 比如Java的常见集合类HashMap,就是用来存储键值对的. 字典中的键( ...

随机推荐

  1. 如何使用excel制作查分系统

    在工作学习中,我们经常会遇到使用excel制作查分系统这样的问题.培根说过:读书足以恬情,足以博采,足以长才.因此,面对使用excel制作查分系统我们应该有努力探索的精神.书到用时方恨少,事非经过不知 ...

  2. JAVA面试题:输出100以内所有的素数

    转载:https://www.cnblogs.com/onway/archive/2012/11/15/2771912.html Java输出1-100中所有的素数 很多人笔试时都会遇到这个问题,小农 ...

  3. io流(io流的引入与文件字节流)

    io流的引入与文件字节流 io流:就是一根吸管,插入后,可以操作目标文件 io流的分类: 按方向:输入,输出 按大小:字节,字符 按处理方式: 处理流:"管套着管" --- 流结合 ...

  4. Git基础知识之内部状态管理系统

    本文主要来介绍一下 Git 的内部状态管理系统.它利用基于节点和指针的数据结构来跟踪及管理编辑操作的时间线. 对本地项目而言,任一时刻,Git 处于三种状态中的一种:工作区状态.暂存区状态和提交区状态 ...

  5. kthread_worker和kthread_work机制

    1.概述 在阅读内核源码时,可以看到kthread_worker.kthread_work两个数据结构配合内核线程创建函数一起使用的场景.刚开始看到这块时,比较困惑,紧接着仔细分析源码后,终于弄清楚了 ...

  6. GO基础知识分享

    目录 GO基础知识分享 go语言的基本事项 关键字 字符串的拼接和变量的定义方式 空白符 const常量 iota的用法 运算符 Go 没有三目运算符,不能适用?: 语言条件语句 for循环的方式 函 ...

  7. [高精度]P1096 Hanoi 双塔问题

    Hanoi 双塔问题 题目描述 给定A.B.C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3的情形). 现 ...

  8. BUAA_OO_2020_第二单元总结

    BUAA_OO_2020_第二单元总结 第一次 设计策略 本次作业采用生产者.消费者模式设计,大致框架如图所示: 生产者:输入线程 消费者:电梯线程 托盘:Dispatcher调度器 线程安全方面,调 ...

  9. CentOS 7.6部署Vue + SrpingBoot + MySQL单体项目

    对于独立的项目(前端.后台单体服务.数据库),部署到新服务器上时,常常需要繁琐的配置与环境安装,这里介绍Centos 7.6下如何搭建基于Docker的环境,以及如何使用docker部署一套Vue + ...

  10. Linux 磁盘管理(df fu fdisk mkfs mount)

    Linux 磁盘管理 Linux磁盘管理好坏直接关系到整个系统的性能问题. Linux磁盘管理常用三个命令为df.du和fdisk. df : 列出文件系统的整体磁盘使用量 du : 检查磁盘空间使用 ...