redis底层数据结构之dict 字典2
2016-07-18 16:39
826 查看
针对 上一文中提出的问题,这一次就进行解答:
由rehash过程可以看出,在rehash过程中,ht[0]和ht[1]同时具有条目,即字典中的所有条目分布在ht[0]和ht[1]中,
这时麻烦也就出来了。主要有以下问题:(现在暂不解答是如何解决的)
1.如何查找key。
2.如何插入新的key。
3.如何删除一个key。
4.如何确保rehash过程不断插入、删除条目,而rehash没有出错。
5.如何遍历dict所有条目,如何确保遍历顺序。
6.如何确保迭代器有效,且正确。
1. 如何查找key
.sizemask;
he = d->ht.table[idx];
while(he) {
if (dictCompareKeys(d, key, he->key))
return he;
he = he->next;
}
//在ht[0]上找不到时,如果现在正进行rehash,key有可能在ht[1]上,需要在ht[1]上查找
if (!dictIsRehashing(d)) return NULL;
}
return NULL;
}.sizemask;
he = d->ht.table[idx];
prevHe = NULL;
while(he) {
if (dictCompareKeys(d, key, he->key)) {
/* Unlink the element from the list */
if (prevHe)
prevHe->next = he->next;
else
d->ht.table[idx] = he->next;
if (!nofree) {
dictFreeKey(d, he);
dictFreeVal(d, he);
}
zfree(he);
d->ht.used--;
return DICT_OK;
}
prevHe = he;
he = he->next;
}
if (!dictIsRehashing(d)) break;
}
return DICT_ERR; /* not found */
}
由rehash过程可以看出,在rehash过程中,ht[0]和ht[1]同时具有条目,即字典中的所有条目分布在ht[0]和ht[1]中,
这时麻烦也就出来了。主要有以下问题:(现在暂不解答是如何解决的)
1.如何查找key。
2.如何插入新的key。
3.如何删除一个key。
4.如何确保rehash过程不断插入、删除条目,而rehash没有出错。
5.如何遍历dict所有条目,如何确保遍历顺序。
6.如何确保迭代器有效,且正确。
1. 如何查找key
dictEntry *dictFind(dict *d, const void *key) { dictEntry *he; unsigned int h, idx, table; if (d->ht[0].size == 0) return NULL; /* We don't have a table at all */ if (dictIsRehashing(d)) _dictRehashStep(d);//如果正在进行rehash,则进行一次rehash操作 h = dictHashKey(d, key);//计算key的哈希值 //先在ht[0]表上查找 for (table = 0; table <= 1; table++) { idx = h & d->ht