PySetObject
本文参考的是 3.8.0a0 版本的代码,详见 cpython 源码分析 基本篇
以后都在 github 更新,请参考 图解 python set
set 的实现方式和 dict 有点类似,但是稍微简单一些,我们来看看 set 的 memory layout
我们来看下 set_lookkey 这个函数
/* Objects/setobject.c
57 - 133 行
*/
static setentry *
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
{
/* 给定一个 key, 和一个 hash 值,返回这个 hash 在这个集合 so 里对应的 entry */
setentry *table;
setentry *entry;
size_t perturb;
size_t mask = so->mask;
size_t i = (size_t)hash & mask; /* 把 hash 高于 mask 长度的位清零,留下长度低于 mask 位数 */
size_t j;
int cmp;
entry = &so->table[i]; /* 取出集合的第 i 个 entry */
if (entry->key == NULL) /* 如果第 i 个 entry 是空的值,直接返回 */
return entry;
perturb = hash;
while (1) {
/* 第i个 entry 不为空, 开始循环匹配,直到找到相等的 entry 为止 */
if (entry->hash == hash) {
/* 如果 entry 里的 hash 值相同,判断 key 是否相同 */
PyObject *startkey = entry->key;
/* startkey cannot be a dummy because the dummy hash field is -1 */
assert(startkey != dummy);
if (startkey == key) /*