Add
如果不在rehash,加在0表
如果在rehash,加到1表上
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
Delete
先删0表。如果在rehash,继续删1表
for (table = 0; table <= 1; table++) {
Update
如果key不存在,那就是Add(如果在rehash,加到1表上)
如果key已经存在,借用Search的逻辑。(在0表就改0表,在1表就改1表)
Search
如果查找的key已经存在了,那么:
不在rehash,查0表;在rehash,查01表
如果查找的key不存在,那么:
不在rehash,返回0表索引;在rehash,返回1表索引(为增做准备)
/* Returns the index of a free slot that can be populated with
* a hash entry for the given 'key'.
* If the key already exists, -1 is returned
* and the optional output parameter may be filled.
*
* Note that if we are in the process of rehashing the hash table, the
* index is always returned in the context of the second (new) hash table. */
static long _dictKeyIndex(dict *d, const void *key, uint64_t hash, dictEntry **existing)
{
unsigned long idx, table;
dictEntry *he;
if (existing) *existing = NULL;
/* Expand the hash table if needed */
if (_dictExpandIfNeeded(d) == DICT_ERR)
return -1;
for (table = 0; table <= 1; table++) {
idx = hash & d->ht[table].sizemask;
/* Search if this slot does not already contain the given key */
he = d->ht[table].table[idx];
while(he) {
if (key==he->key || dictCompareKeys(d, key, he->key)) {
if (existing) *existing = he;
return -1;
}
he = he->next;
}
if (!dictIsRehashing(d)) break;
}
return idx;
}
Summary
增: 在rehash,一定加在1表
删: 可以简单认为01两表都会删
改(key已经存在,做修改): 在0表就改0表,在1表就改1表
改(key不存在): 那就是增
查: 可以简单认为01两表都会查(一定最多只在一个表中出现)
网友评论