redis6.0源码学习 (四)dict

redis6.0源码学习 (四)dict


redis dict主要实现文件为src/dict.c 和dict.h,实现了 insert / del / replace / find / get-random-element操作。哈希表会自动以调整大小,冲突通过链接处理。

1、数据结构

1.1 dictht

在看dict得结构前,先看下dict中的dicht (hash表)结构,下面是hash表结构的定义:

typedef struct dictht { //hash表结构定义,每一个dict有两个,在rehash过程中会用到两个。
    dictEntry **table; // 哈希表节点指针数组(俗称桶,bucket)
    unsigned long size; // 指针数组的大小
    unsigned long sizemask; // 指针数组的长度掩码,用于计算索引值
    unsigned long used;  // 哈希表现有的节点数量
} dictht;

在这里插入图片描述

1.2 dictEntry

下面是hash表节点的定义

typedef struct dictEntry {
    void *key; //键
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v; //值
    struct dictEntry *next;//在存在hash冲突的时候,用来链接具有相同hash值得key/val对,如下图所示。
} dictEntry;

下图展示了dictEntry在dictht中存储示意图:
在这里插入图片描述

1.3 dict

下面是redis字典定义的结构:

typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2]; //两个hash表
    long rehashidx; /*记录 rehash 进度的标志,值为 -1 表示 rehash 未进行*/
    unsigned long iterators; /* 当前正在运作的安全迭代器数量*/
} dict;
  • dictType *type:一个指向dictType结构的指针(type)。它通过自定义的方式使得dict的key和value能够存储任何类型的数据。
  • void *privdata:一个私有数据指针。由调用者在创建dict的时候传进来。
  • dictht ht[2]:两个哈希表,只有在rehash的过程中,ht[0]和ht[1]才都有效。一般情况下,只有ht[0]有效,ht[1]里面没有任何数据。
  • long rehashidx:当前rehash索引(rehashidx)。如果rehashidx = -1,表示当前没有在rehash过程中;否则,表示当前正在进行rehash,且它的值记录了当前rehash进行到哪一步了。
  • unsigned long iterators:当前正在进行遍历的iterator的个数。这不是我们现在讨论的重点,暂时忽略。

下面是字典类型定义:

typedef struct dictType {
    //对key进行哈希值计算的哈希算法
    uint64_t (*hashFunction)(const void *key);
    //keyDup和valDup: 分别定义key和value的拷贝函数,用于在需要的时候对key和value进行深拷贝,而不仅仅是传递对象指针
    void *(*keyDup)(void *privdata, const void *key);
    void *(*valDup)(void *privdata, const void *obj);
    //定义两个key的比较操作,在根据key进行查找时会用到
    int (*keyCompare)(void *privdata, const void *key1, const void *key2);
    //keyDestructor和valDestructor: 分别定义对key和value的析构函数
    void (*keyDestructor)(void *privdata, void *key);
    void (*valDestructor)(void *privdata, void *obj);
} dictType;

下面是dict的示意图:
在这里插入图片描述

2、dict的创建

/* Reset a hash table already initialized with ht_init().
 * NOTE: This function should only be called by ht_destroy(). */
static void _dictReset(dictht *ht)
{
    ht->table = NULL;
    ht->size = 0;
    ht->sizemask = 0;
    ht->used = 0;
}

/* Create a new hash table */
dict *dictCreate(dictType *type,
        void *privDataPtr)
{
    dict *d = zmalloc(sizeof(*d));

    _dictInit(d,type,privDataPtr);
    return d;
}

/* Initialize the hash table */
int _dictInit(dict *d, dictType *type,
        void *privDataPtr)
{
    _dictReset(&d->ht[0]);
    _dictReset(&d->ht[1]);
    d->type = type;
    d->privdata = privDataPtr;
    d->rehashidx = -1;
    d->iterators = 0;
    return DICT_OK;
}

3、 元素的查找、插入和删除

4、 rehash过程

5、总结

待续。。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值