美文网首页
Redis 源码--字典 P1.字典结构。

Redis 源码--字典 P1.字典结构。

作者: namelessEcho | 来源:发表于2017-10-01 10:40 被阅读0次

字典是一种进行利用key快速查找value的key-value结构。从定义上来说key应该具有唯一性,即从编程语言的层面上来说,一个字典里不能存在两个语义相同的key。同样的C也没有自己的字典实现,于是Redis实现了自己的字典。
Redis的字典是通过HashTable来实现的,相比红黑树,hash的实现真的挺简单了。Hahs表必须要解决hashode的冲突问题(hashcode的冲突并不意味中hashcode一定是相等的。),常见的解决方法是拉链法和线性探测法。
简单来说拉链法是使用一个桶(bucket)来聚集所有hashcode()冲突的key,而线性探测则是将冲突的key简单的后移。
Redis的HashTable的实现方法是拉链法。通过两个table的渐进式的hash,保证了性能不会有太大的损失。
与链表类似,Redis使用了一个dict结构来操作字典(dict)。

typedef struct dict {

    // 类型特定函数
    dictType *type;

    // 私有数据
    void *privdata;

    // 哈希表
    dictht ht[2];

    // rehash 索引
    // 当 rehash 不在进行时,值为 -1
    int rehashidx; /* rehashing not in progress if rehashidx == -1 */

    // 目前正在运行的安全迭代器的数量
    int iterators; /* number of iterators currently running */

} dict;

逐个来看一下里面的结构:第一个是dicTtype结构体,其定义如下,主要存储了所使用的各个用于HashTable操作的函数指针。

typedef struct dictType {

    // 计算哈希值的函数
    unsigned int (*hashFunction)(const void *key);

    // 复制键的函数
    void *(*keyDup)(void *privdata, const void *key);

    // 复制值的函数
    void *(*valDup)(void *privdata, const void *obj);

    // 对比键的函数
    int (*keyCompare)(void *privdata, const void *key1, const void *key2);

    // 销毁键的函数
    void (*keyDestructor)(void *privdata, void *key);
    
    // 销毁值的函数
    void (*valDestructor)(void *privdata, void *obj);

} dictType;

void *privdata是保存的传给dictType的可选参数。

dictht ht[2]声明的两个结构体数组。

typedef struct dictht {
    
    // 哈希表数组
    dictEntry **table;

    // 哈希表大小
    unsigned long size;
    
    // 哈希表大小掩码,用于计算索引值
    // 总是等于 size - 1
    unsigned long sizemask;

    // 该哈希表已有节点的数量
    unsigned long used;

} dictht;

其中最主要的结构应该是dictEntry 数组dictEntry **table,它定义了size个保存dictEntry 的桶(解决链冲突)的数组。dictEntry是每个hash表的结点,是保存每个key-value对的实体。

typedef struct dictEntry {
    
    // 键
    void *key;

    // 值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;

    // 指向下个哈希表节点,形成链表
    struct dictEntry *next;

} dictEntry;

可以看到redis在值内部允许一个指向任意值的指针,或者是一个64位的无符号数,亦或是64的有符号数。

总的来说:在文档里是这写的:
Hash tables will auto-resize if needed

  • tables of power of two in size are used, collisions are handled by
  • chaining.

dictEntry数组会以2的指数倍的形式进行自动扩容,键冲突通过拉链法完成。

相关文章

  • Redis 源码--字典 P1.字典结构。

    字典是一种进行利用key快速查找value的key-value结构。从定义上来说key应该具有唯一性,即从编程语言...

  • Redis 设计与实现 4:字典 dict

    Redis 中,字典是基础结构。Redis 数据库数据、过期时间、哈希类型都是把字典作为底层结构。 字典的结构 哈...

  • Redis学习笔记---数据类型

    Redis是REmote DIctionary Server(远程字典服务器)的缩写,它以字典结构存储数据。现在我...

  • redis-字典

    redis所使用的C语言并没有内置丰富的数据结构,因而redis实现了很多数据结构,本文主要介绍字典。 字典又叫映...

  • redis底层数据组织方式

    底层数据结构 redis底层数据结构有:字典、双端链表、压缩链表、整数集合、跳跃表和字典、整数集合、embstr ...

  • redis散列类型HSET

    redis采用字典结构以键值对的形式存储数据,散列类型(hash)的键值也是一种字典结构,其存储了字段(filed...

  • Redis数据结构--字典

    字典是Redis的重要数据结构,Redis的数据库就是使用字典作为底层实现的。代码位于dict.h和dict.c中...

  • Redis 数据结构之字典

    redis的字典数据结构是由哈希表实现的,字典内设有两个哈希表,一个用于存储数据,一个用于rehash时使用。字典...

  • 【Redis5.X源码分析】系列之字典

    引入字典 从本文开始慢慢揭开Redis字典的神秘面纱,字典又称为散列表,用来存储键值对的一种数据结构,在很多高级语...

  • Redis 数据结构与内存管理策略(下)

    字典(dict) dict字典是基于hash算法来实现,是Hash数据类型的底层存储数据结构。我们来看下redis...

网友评论

      本文标题:Redis 源码--字典 P1.字典结构。

      本文链接:https://www.haomeiwen.com/subject/buxbextx.html