Redis 字典(Dictionary)是其核心数据结构之一,用于实现诸如数据库的键空间、哈希表、集合、有序集合等高级数据结构的基础存储。在源码中,字典的定义和接口主要位于dict.h
文件中,而具体实现则在dict.c
中。以下是基于dict.h
的学习要点:
数据结构定义
-
dictEntry:表示字典中的一个键值对条目。
typedef struct dictEntry { void *key; // 键 union { void *val; // 值 uint64_t u64; // 整数值的优化存储 int64_t s64; // 整数值的优化存储 } v; struct dictEntry *next; // 指向哈希冲突链表的下一个节点 } dictEntry;
-
dictType:定义了操作特定类型键值对的函数指针集合。
typedef struct dictType { uint64_t (*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;
-
dict:字典结构体,包含两个哈希表(用于渐进式rehash)、类型定义、引用计数等。
typedef struct dict { dictType *type; // 操作函数集 void *privdata; // 私有数据,供类型操作函数使用 dictht ht[2]; // 哈希表,ht[0]为当前表,ht[1]为rehash时的新表 int rehashidx; // rehash标志,-1表示未进行rehash unsigned long iterators; // 正在进行的迭代器数量 } dict;
关键操作接口
- dictCreate:创建一个新的字典实例。
- dictFind:查找给定键对应的值。
- dictAdd:向字典中添加新的键值对,如果键已存在则更新其值。
- dictDelete:删除指定键的键值对。
- dictRehash:渐进式rehash,逐步将旧哈希表的数据迁移到新哈希表中,以应对哈希表负载因子过高或缩容等情况。
- dictIterator:创建一个用于遍历字典的迭代器。
- dictNext:使用迭代器遍历字典的下一个元素。
学习要点
- 哈希实现:理解Redis如何使用哈希函数将键映射到哈希表的槽位上,以及如何处理哈希冲突。
- 渐进式rehash:深入掌握Redis如何在不影响服务的情况下平滑地调整哈希表大小,这是一个重要的性能优化手段。
- 内存管理:注意Redis如何高效地管理字典及其内部元素的内存,包括使用引用计数等机制。
- 自定义类型:探索如何通过
dictType
自定义键值对的处理方式,以支持特殊的数据类型或操作逻辑。
通过深入学习dict.h
,你可以理解Redis如何利用字典这一基础数据结构来支撑其高效、灵活的键值存储能力。