Redis 源码解读——字典

文章目录

四个数据结构

dictEntry

dictEntry 的结构如下(Redis 7.0):

typedef struct dictEntry {
    void *key; // 键
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v; // 值
    struct dictEntry *next;     /* Next entry in the same hash bucket.即下一个节点 */
    void *metadata[];           /* An arbitrary number of bytes (starting at a
                                 * pointer-aligned address) of size as returned
                                 * by dictType's dictEntryMetadataBytes(). */
} dictEntry;

可以对比 《Redis 设计与实现》中的 dictEntry 结构,发现联合结构 v 中多了一个 double 的浮点数表示,metadata 是一块任意长度的数据,具体的长度由 dictType 中的 dictEntryMetadataBytes() 返回,作用相当于 privdata

dictType

dictType 是一系列操作字典的键和值的操作:

typedef struct dictType {
    uint64_t (*hashFunction)(const void *key); // 哈希函数
    void *(*keyDup)(dict *d, const void *key); // 复制键的函数
    void *(*valDup)(dict *d, const void *obj); // 复制值的函数
    int (*keyCompare)(dict *d, const void *key1, const void *key2); // 键的比较
    void (*keyDestructor)(dict *d, void *key); // 键的销毁
    void (*valDestructor)(dict *d, void *obj); // 值的销毁
    int (*expandAllowed)(size_t moreMem, double usedRatio); // 字典里的哈希表是否允许扩容
    /* Allow a dictEntry to carry extra caller-defined metadata.  The
     * extra memory is initialized to 0 when a dictEntry is allocated. */
    /* 允许调用者向条目 (dictEntry) 中添加额外的元信息.
     * 这段额外信息的内存会在条目分配时被零初始化. */
    size_t (*dictEntryMetadataBytes)(dict *d);
} dictType;

该结构是为了实现字典的多态。

dict

7.0 版本的字典结构如下:

struct dict {
    dictType *type;

    dictEntry **ht_table[2];
    unsigned long ht_used[2];

    long rehashidx; /* rehashing not in progress if rehashidx == -1 */

    /* Keep small vars at end for optimal (minimal) struct padding */
    int16_t pauserehash; /* If >0 rehashing is paused (<0 indicates coding error) */
    signed char ht_size_exp[2]; /* exponent of size. (size = 1<<exp) */
};

相比于 《Redis 设计与实现》中的字典实现,改动较大,7.0中去掉了 dictht 结构,即去掉了哈希结构。接下来介绍每个成员:

/* 	type 上面已经解释过了;
*	ht_table 即哈希表数组
*	ht_used 分别表示哈希表数组中各自已经存放键值对的个数
*	rehashidx 是 rehash 时用的,没有 rehash 时值为1
*	pauserehash 则是表示 rehash 的状态,大于0时表示 rehash 暂停了,小于0表示出错了
*	ht_size_exp 则是表示两个哈希表数组的大小,通过 1 << ht_size_exp[0/1] 来计算
*/

我们可以看到一行注释:/* Keep small vars at end for optimal (minimal) struct padding */ ,将小变量放在结构体的后面,为了最佳或最小的填充,即节省空间。

dictIterator

dictIterator 是字典的迭代器

/* If safe is set to 1 this is a safe iterator, that means, you can call
 * dictAdd, dictFind, and other functions against the dictionary even while
 * iterating. Otherwise it is a non safe iterator, and only dictNext()
 * should be called while iterating. */
typedef struct dictIterator {
    dict *d;
    long index;
    int table, safe;
    dictEntry *entry, *nextEntry;
    /* unsafe i
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值