redis字典

字典

  • 字典就是map,一种保存键值对的抽象数据结构

  • 字典里的每个键都是独一无二的,程序就是通过键来查其对应的值

  • 但C语言也没有内置map,因此redis自己构建的字典

  • 在Redis中,哈希键(Hash key)是一种特殊的键类型,它是一个字符串,其值是一个哈希表。哈希表中可以存储多个键值对

  • 字典就是哈希键的底层实现之一,当一个哈希键包含的键值对比较多,又或者键值对中的元素都是比较长的字符串时,Redis会使用字典作为底层实现哈希键

  • Redis使用哈希表来实现的字典,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对

  • 哈希表:

    • typedef struct dictht {//哈希表数组dictEntry **table;//哈希表大小unsigned long size;//哈希表大小掩码,用于计算计算索引unsigned long sizemask;//哈希表已有节点的数量unsigned long used;
      } dictht;
      
  • table为一个数组,里面的每个元素指向dictEntry结构的指针

  • size记录了哈希表的大小,即数组table的大小

  • used记录了哈希表已有节点的数量

  • sizemask = size - 1,这个属性和哈希值一起决定一个键应该被放到数组table哪个索引上面

  • 哈希表节点:

    typedef struct dictEntry {//键void *key;//值union{void *val;uint64_t u64;int64_t s64;} v;//指向下一个节点struct dictEntry *next;
    } dictEntry;
    
    • v属性保持着键值对中的值,值可以是一个指针,或者一个uint64_t整数,又或者是一个int64_t整数

    • next是指向另一个节点的指针,这个指针可以将多个哈希值相同的键值对连接在一次,以此解决键冲突的问题

  • 字典:

    • typedef struct dict {//类型特定函数dictType *type;//私有函数void *privdata;//哈希表dictht ht[2];//rehash索引//当rehash不在进行时,值为-1int rehashidx;
      } dict;
      
      • type属性和privdata属性是针对不同类型的键值对,为创建多态字典而设置的
      • ht是一个包含两个项的数组,每个项都是一个dictht哈希表,一般情况使用ht[0]哈希表,ht[0]表rehash时才会去使用ht[1]
      • rehashidx记录了rehash目前的进度
    • typedef struct dictType {
      一些操作键的函数
      } dictType; 	 
      
  • 哈希算法:

    • 当添加一个新的键值对进字典的时候,程序需要根据键值对的键计算出哈希值和索引值,再将包含键值对的哈希表节点放在哈希表数组的指定索引上去
      1. 使用字典设置的哈希函数,计算key的哈希值
      2. 使用哈希表的sizemask属性和哈希值,计算出索引值
      3. 根据情况不同,选择哈希表数组加入,ht[x]可能时ht[0]或者ht[1]
    • MurmurHash算法是08年发明的,优点在于, 即使输入的键是非常有规律的,但算法仍然可以给出很好的随机分布性,计算速度也非常快
    • MurmurHash最新的版本是MurmurHash3,redis使用的是MurmurHash2
  • 解决键冲突:

    • 当有两个以上的键被分配到了哈希表数组的同一个索引上了,我们称这些键发生了冲突
    • reids的哈希表使用链地址法来解决键冲突,每个哈希表节点都有一个next指针,分配在同一个索引上的多个节点可以通过next指针构成一个链表
    • 因为dictEntry节点组成的链表没有指向链表表尾的指针,所以为速度考虑,程序总是将新节点添加到表头,时间复杂度为O(1)
  • rehash(重新散列):

    • 为了让哈希表的负载因子维持在一个合理的范围内,也就是说哈希表保存的键值对数量不能太多也不能太少,程序需要对哈希表的大小进行相应的拓展或收缩
    • 先要理解used的节点是可能小于存于的键值对的,毕竟在一个节点那可以形成一条链表
    • 而这个扩展和收缩哈希表的工作就可以通过执行rehash来完成
    1. 如果是拓展操作:ht[1]的大小是为第一个大于等于ht[0].used *2的(2的n次方幂)
    2. 如果是收缩操作:ht[1]的大小为第一个大于等于ht[0].used 的(2的n次方幂)
    3. 将保存在ht[0]的所有键值对rehash到ht[1]上:rehash指的是重新计算键的哈希值和索引值,然后将键值对放置到ht[1]哈希表指定位置上
    4. 当ht[0]的所有键值对都迁移到ht[1]上之后,释放ht[0],将ht[1]设置为ht[0],并在ht[1]新创建一个空白哈希表,为下次rehash做准备
  • 哈希表的扩展与收缩:

    • 负载因子= ht[0].used / ht[0].size
    • 扩展的条件:
      1. 服务器没有进行BGSAVE或者BGREWRITEAOF命令,并且哈希表的负载因子 >= 1
      2. 哈希表的负载因子 >= 5
    • 收缩的条件:哈希表的负载因子 <= 0.1
  • 渐进式rehash:

    • rehash操作并不是一次性,集中做的,而是分多次、渐进式地完成

    • 这样做的原因是,如果含有的键值对太多的话,庞大的计算量会使服务器在一段时间内停止服务

    • 渐进式rehash的步骤:

      • 为ht[1]分配空间
      • 将rehashidx设置为0,表示rehash开始了
      • 在rehash期间,删除、查找、更新时,程序除了执行指定操作,还会将ht[0]哈希表在rehashidx处的所有键值对全部rehash到ht[1],一次rehash完成,rehashidx加一
      • 每次对字典执行添加操作,直接将键值对添加到ht[1],保证ht[0]只减不增,直到ht[0]全空
      • 等到所有键值对rehash完,就将rehashidx设置为 -1,表示rehash完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/30404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人工智能—美国加利福尼亚州房价预测实战

引言 在当今快速发展的房地产市场中&#xff0c;房价预测已成为一个至关重要的领域。它不仅关系到投资者的决策&#xff0c;也直接影响到普通购房者的生活质量。特别是在美国加利福尼亚州&#xff0c;这个以其高房价和房地产市场的波动性而闻名的地方&#xff0c;准确的房价预…

TF-IDF、BM25传统算法总结

1. TF-IDF算法 F-IDF&#xff08;词频-逆文档频率&#xff09;是一种用于衡量文本中词语重要性的方法&#xff0c;特别适用于信息检索和文本挖掘任务。下面会拆分为两部分深入讲解TF-IDF的计算过程&#xff0c;以便更好地理解。 TF-IDF的计算过程可以分为两个主要部分&#xf…

【漏洞复现】契约锁电子签章平台 add 远程命令执行漏洞(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

Redis(基础篇)

Redis是一个可基于内存也可持久化的Key-Value数据库也称非关系型&#xff08;NoSQL&#xff09;数据库。 传统关系型数据库是结构化数据&#xff0c;每张表在创建的时候都有严格的约束信息&#xff0c;如字段名、字段数据类型、字段约束等&#xff0c;插入的数据必须遵循这些约…

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系(m_coord)

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系&#xff08;m_coord&#xff09; 0. 引言1. m_proj使用方法2. 结语 0. 引言 上一篇介绍了m_proj函数用于初始化投影&#xff0c;本篇介绍的函数m_coord用于初始化地理坐标系或地磁坐标系&#xff0c;地理/地磁坐标系和投影…

xss一些笔记

&#xff08;乱写的一些笔记&#xff09; innerHTML只防script像是img就不会防 innerText都防 上面代码执行避免用户交互 js也可以用’‘执行 例子 alert’1‘ document.location.hash // #号后的部分&#xff0c;包括#号 document.location.host // 域名…

黑马苍穹外卖4 店铺营业状态设置+Redis基础

店铺营业状态设置 Redis MySQL Java并发 JavaMVC 计算机网络 操作系统 算法&#xff0c;后端面试主要是这些&#xff0c;外加项目 Redis 数据库&#xff0c;基于内存存储的key-value结构。 mysql是磁盘存储&#xff0c;通过二维表存储。 在文件夹目录打开cmd 服务端&#xf…

YOLOv10(6):YOLOv10基于TensorRT的部署(基于INetworkDefinition)

1. 写在前面 我们在前面已经讲过很多关于YOLOv10的一些知识点&#xff0c;也简单理了一下如何训练自己的数据。 现在本篇文章主要是讲解一下如何在TensorRT中部署YOLOv10&#xff0c;相信经过这一步&#xff0c;各位小伙伴已经能够无限的接近于将YOLOv10产品化了。 另一个需要说…

Google Hacking 搜索语法及其功能

目录 ①常见语法及其功能Ⅰ关键词:搜索内容Ⅱ逻辑运算符使用1. AND 运算符2. OR 运算符3. NOT 运算符综合示例 ②综合搜索案例案例 1&#xff1a;查找某网站的登录页面案例 2&#xff1a;查找包含密码的 Excel 文件案例 3&#xff1a;查找某网站的所有 PDF 文件案例 4&#xff…

Spring Boot框架的原理及应用详解(四)

本系列文章简介&#xff1a; 在当今的软件开发世界中&#xff0c;快速迭代、高效开发以及易于维护成为了开发者们不断追求的目标。Spring Boot作为Spring框架的一个子项目&#xff0c;自其诞生以来就凭借其“约定大于配置”的理念和自动配置的特性&#xff0c;迅速在Java开发社…

LeetCode-day17-2713. 矩阵中严格递增的单元格数

LeetCode-day17-2713. 矩阵中严格递增的单元格数 题目描述示例示例1&#xff1a;示例2&#xff1a;示例3&#xff1a; 思路代码 题目描述 给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat&#xff0c;你可以选择任一单元格作为 起始单元格 。 从起始单元格出发&#xff…

Ribbon与Nginx的区别

负载均衡实现的位置不同&#xff1a; Ribbon&#xff1a;负载均衡器位于客户端&#xff0c;不需要单独搭建。Nginx&#xff1a;需要建立一个独立负载均衡服务器&#xff0c;服务端。 负载均衡策略&#xff1a; Ribbon&#xff1a;提供了多种负载均衡策略&#xff0c;如随机策…

Perplexity AI — 探索网络,发掘知识,沟通思想

体验地址&#xff1a;Perplexity AI &#xff08;国外网站访问需要梯子&#xff09; Perplexity AI是一款功能强大的人工智能搜索引擎&#xff0c;其特点和优势主要体现在以下几个方面&#xff1a; 功能&#xff1a; 自然语言搜索&#xff1a;Perplexity AI可以理解用户的自然…

C类IP介绍

一、C类ip给谁用&#xff1a; 局域网常用的就是C类地址。 二、基本介绍 ip地址范围 - 理论范围 192.0.0.0 ~ 223.255.255.255&#xff1a;11000000 00000000 00000000 00000000 ~ 11011111 11111111 11111111 11111111 - 实际&#xff08;正常情况&#xff09;可用地址范围 1…

Shopify 如何实现 Sticky 功能

Shopify 如何实现 Sticky 功能 介绍 在网页设计中&#xff0c;Sticky 功能是一种常见的技术&#xff0c;它使得网页上的元素在滚动时保持固定位置。这对于创建吸引人的用户体验和提高网站的可用性非常重要。Shopify 作为一个流行的电商平台&#xff0c;提供了丰富的功能和工具…

c++的多态,继承,抽象类,虚函数表,虚函数等题目+分析

目录 题目 代码题 分析 主观题 题目 代码题 class A { public:virtual void func(int val 1) {std::cout << "A->" << val << std::endl;}virtual void test() { func(); } };class B : public A { public:void func(int val 0) { std…

如何在服务器上部署一个java程序

如何在服务器上部署一个java程序&#xff1f; 一、在服务器上安装jdk环境 1.创建目录用于存放jdk文件 cd /usr/local 2.下载最新版oracle jdk22 wget https://download.oracle.com/java/22/latest/jdk-22_linux-x64_bin.tar.gz 3.解压 tar -zxf jdk-22_linux-x64_bin.ta…

进化版ChatGPT的Siri今年无缘上线!苹果正打造史上最薄iPhone 17

目录 01 超强Siri助手预计2025年上线 02 集成ChatGPT但没有买单 03 iPhone 17更轻薄 最新报道称&#xff0c;苹果的AI功能将在未来几个月逐步推出&#xff0c;并持续到2025年。 据称&#xff0c;今年夏天结束前&#xff0c;开发者们仍无法试用和体验。 因此&#xff0c;在即…

MySQL系列-语法说明以及基本操作(一)

1、前言 主要讲解MySQL的基本语法 官网文档 https://docs.oracle.com/en-us/iaas/mysql-database/doc/getting-started.html 关于MySQL的基本语法&#xff0c;关于数据类型、表的操作、数据操作、事务、备份等&#xff0c;可参考 http://www.voidme.com/mysql 2、数据类型 数…