关闭

Redis源码分析(三)——Redis数据结构-字典

标签: redis数据结构源码typedefstruct
1503人阅读 评论(0) 收藏 举报
分类:

这里写图片描述

1. 数据结构

1.1 哈希表

typedef struct dictht{
  dictEntry **table;
  unsigned long size;
  unsigned long sizemask;
  unsigned long used;
} dictht;
  • table:存储节点的数组
  • size:table数组的长度
  • sizemask:size-1,用于在添加节点时计算节点在table中的位置
  • used:节点数量

1.2 哈希表节点

typedef struct dictEntry{
  void *key
  union {
    void *val;
    unit64_t u64;
    int64_t s64;
  }v;
  struct dictEntry *next
} dictEntry;
  • key:节点的key
  • union:节点的value(可以是指针、unit64_t整数、int64_t整数)
  • next:下一个节点的地址

1.3 字典

typedef struct dict {
  dictType *type
  void *privdata
  dictht ht[2]
} dict;
  • type:操作哈希表的各种函数
  • privdata:上述函数所需的入参
  • ht[2]:存储两个哈希表,一个正常使用,另一个在rehash时使用。

2. 哈希算法

  1. 计算哈希值

    hash = dict->type->hashFunction(key);
  2. 计算在table数组的位置

    index = hash & dict->ht[0].sizemask;
  3. 插入节点
    创建新节点,并将其插入到table[index]的第一位。

3. rehash

3.1 何时进行rehash?

当加载因子(load factor)大于1或小于0.1时就要进行rehash。
加载因子计算公式:

load_factor = ht[0].used / ht[0].size

3.2 新哈希表大小的计算公式

当需要进行扩容/缩容的时候,究竟创建多大的哈希表呢?这取决于如下公式:

  • 若要进行扩容,则新的哈希表的大小=第一个大于等于h[0].used*2的2的n次方。
  • 若要进行缩容,则新的哈希表的大小=第一个大于等于h[0].used的2的n次方。

3.3 rehash过程

  1. 创建一个新的哈希表h[1],大小由上述公式计算得出;
  2. 将字典的rehashidx值从-1改为0;
  3. 依次遍历ht[0]上的所有节点,依次转移到ht[1]上去;
  4. 释放ht[0]的内存空间;

3.4 渐进式rehash

  • rehash过程中需要将所有节点迁移到新的哈希表中,如果节点个数很多的情况下,迁移的过程将非常漫长,那么程序将处于停止等待状态。所以事实上,Redis的rehash过程是分多次、分布完成的。
  • 在rehash过程中,每次对哈希表进行增删改查外,还要将ht[0][rehashidx]上的所有节点迁移到ht[1]中,并将rehashidx+1。从而几次操作后,ht[0]上的所有节点均被迁移至ht[1]中,rehash过程完成。
  • 在rehash过程中,对哈希表的添加操作均在ht[1]上完成,ht[0]只减不增。

这里写图片描述

1
0
查看评论

Redis源码解析——字典结构

Redis字典库的接触结构
  • breaksoftware
  • breaksoftware
  • 2016-12-08 20:25
  • 1391

Redis内部数据结构详解之字典(dict)

本文所引用的源码全部来自Redis2.8.2版本。 Redis中字典dict数据结构与API相关文件是:dict.h, dict.c。 本文讲解的不是很详细,可以同时参考Redis实现与设计一书中字典部分,本文关于字典的核心代码的注释可以参考。 字典,简单说就是存储key-value键值...
  • Acceptedxukai
  • Acceptedxukai
  • 2013-12-22 16:44
  • 7687

【Redis源码剖析】 - Redis内置数据结构之字典dict

今天我们来讲讲Redis中的哈希表。哈希表在C++中对应的是map数据结构,但在Redis中称作dict(字典)。Redis只是用了几个简单的结构体和几种常见的哈希算法就实现了一个简单的类似高级语言中的map结构。下面我们来具体分析一下dict的实现。
  • Xiejingfa
  • Xiejingfa
  • 2016-03-30 19:08
  • 24384

Redis中的字典

Redis中的字典  字典,又称为符号表(symbol table)、关联数组(associative array)或映射(map),是一种用于保存键值对(key-value pair)的抽象数据结构。  在字典中,一个键(key)可以和一个值(value)进行关联(或者说将键映射为值),这些关联的...
  • universe_ant
  • universe_ant
  • 2016-04-09 22:56
  • 974

redis学习笔记(3)---字典dict

字典dict  redis中的字典,即hash表,其实现与Java中的HashMap基本类似。同样是基于数组和链表的,通过“拉链法”来处理碰撞。   字典中的每一个key都是独一无二的,当要加入一个key-value对时,如果key在字典中已经存在,则会直接返回,而不会重新将其加入到字典中。字典...
  • u012658346
  • u012658346
  • 2016-05-04 16:29
  • 1297

Redis系列----(二)redis中的数据结构类型

一.前言 redis并不是简单的key-value数据容器,不能将其理解为静态存储数据,它是动态交互的数据结构服务器,可以被用作缓存,高性能k-v数据库等。 它支持很多种类型的数据结构,不仅支持string类型的value,还支持很多种复杂类型的数据。以下简单列出redis支持的数据类型,后续再对每...
  • u013035972
  • u013035972
  • 2016-09-11 21:54
  • 7832

【Redis源码剖析】 - Redis内置数据结构之压缩列表ziplist

Redis提供了一种称作ziplist的数据结构,称作压缩列表。ziplist使用一串字符串来实现双向链表结构。与list结构相比,ziplist可以减少存储空间(主要是节省了链表指针的存储空间开销),ziplist在实现上并不存储上指向上一个链表节点和指向下一个链表节点的指针,而转为存储上一个节点...
  • Xiejingfa
  • Xiejingfa
  • 2016-04-06 13:53
  • 5731

redis中的5种数据结构

这里的数据结构指的是key-value中value的数据结构,分别为string、hash、list、set、sorted set。每种数据结构都有相关的命令,比如set命令表示使用string来存储value,get命令的参数只能为对应value值存储为string的key,操作其他数据结构需要相...
  • imred
  • imred
  • 2016-04-22 22:24
  • 4643

redis的五种数据结构

reids官方命令集查询: http://redis.io/commands redis整合各种语言案例查询: https://github.com/josiahcarlson/redis-in-action redis可以存储键和五种不同类型的值之间的映射 String字符串 List...
  • fan510988896
  • fan510988896
  • 2017-05-12 15:17
  • 656

redis常用数据结构解析

Redis是一个开源的Key-Value存储引擎,它支持string、hash、list、set和sorted set等多种值类型。由于其卓越的性能表现、丰富的数据类型及稳定性,广泛用于各种需要k/v存储的场景。甚至在一些分布式缓存系统中,也用它作为底层存储引擎。本文对redis最常用的数据类型进行...
  • yueqian_zhu
  • yueqian_zhu
  • 2016-01-17 16:48
  • 2201
    个人资料
    • 访问:361465次
    • 积分:5639
    • 等级:
    • 排名:第5541名
    • 原创:199篇
    • 转载:8篇
    • 译文:0篇
    • 评论:155条
    我的微信公众号
      大闲人柴毛毛
      一个分享技术干货和记录程序员奋斗史的地方。快关注我吧!
    博客专栏
    最新评论