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. SpringDataJPA 入门

    前言 1. 三者的区别与联系 JPA:本身是一种ORM规范,不是ORM框架.由各大ORM框架提供实现. Hibernate是一个完整的ORM框架,常规CRUD我们不需要写一句SQL;框架比较重,学习成 ...

  2. WPF 基础 - 启动与退出及异常捕获

    1. 若需要控制 exe 实例数量 bool ret; mutex = new System.Threading.Mutex(true, exename, out ret); if (!ret) { ...

  3. Python-jet后台管理的使用

    python-django-jet库的使用 1.安装 pip install django-jet 2.配置 将'jet'应用添加到你的Django项目的设置文件settings.py中的INSTAL ...

  4. 一种借助POI粗略的标注城市也许重要的区域的方法

    第一部分 很久以前,我住在村子里,因为村子小,所以对村子的一草一木都很熟悉,在熟悉的环境里就很有安全感. 后来我到了大城市,却发现城市太大了,一辈子都熟悉不完. 这个城市的绝大部分地方我都没有去过,就 ...

  5. (三)SpringBoot启动过程的分析-创建应用程序上下文

    -- 以下内容均基于2.1.8.RELEASE版本 紧接着上一篇(二)SpringBoot启动过程的分析-环境信息准备,本文将分析环境准备完毕之后的下一步操作:ApplicationContext的创 ...

  6. 通过《第一行代码》学习 Android 开发

    第一行代码 Android --第 2 版-- 郭霖 著 第 1 章:开始启程--你的第一行 Android 代码 •1.2 手把手带你搭建开发环境  Android Studio 的安装及配置  A ...

  7. [矩阵乘法]裴波拉契数列III

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I I [矩阵乘法]裴波拉契数列III [矩阵乘法]裴波拉契数列III Description 求数列f[n]=f[n-1]+f[n-2]+1的第N ...

  8. Jmeter(四十二) - 从入门到精通进阶篇 - Jmeter配置文件的刨根问底 -番外篇(详解教程)

    1.简介 为什么宏哥要对Jmeter的配置文件进行一下讲解了,因为有的童鞋或者小伙伴在测试中遇到一些需要修改配置文件的问题不是很清楚也不是很懂,就算修改了也是模模糊糊的.更有甚者觉得那是禁地神圣不可轻 ...

  9. Python函数参数和注解是什么

    四种参数 Python函数func定义如下: def func(first, *args, second="Hello World", **kwargs): print(first ...

  10. centos 7升级gcc到10.2.0

    安装gcc 由于 Linux 操作系统的自由.开源,在其基础上衍生出了很多不同的 Linux 操作系统,如 CentOS.Ubuntu.Debian 等.这些 Linux 发行版中,大多数都默认装有 ...