redis dict

typedef struct dictEntry {            // dictEntry: 哈希表节点,每个dictEntry保存一个键值对
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;        // next用于将hash值相同的键值对连接起来
} dictEntry;
 
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;
 
/* This is our hash table structure. Every dictionary has two of this as we
* implement incremental rehashing, for the old to the new table. */
typedef struct dictht {        // hash table
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;
 
typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;
 
/* 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 iterator fingerprint for misuse detection. */
    long long fingerprint;
} dictIterator;
 
1.dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing),插入一个key
    1.若为key的dictEntry已经存在,则existing指向已经存在的dictEntry,并返回NULL
    2.否则,生成一个dictEntry,加入到d->ht中(如果在rehash,放入ht[1],否则放入ht[0]),并设置该dictEntry的key为参数key,并返回该dictEntry
 
2.int dictReplace(dict *d, void *key, void *val),向一个指定key插入value
    1.调用dictAddRaw,返回值—>entry
    2.如果entry不为空,说明是新生成的dictEntry,设置其value;否则,该entry已经存在,设置新value,free旧value
 
3.dictEntry *dictAddOrFind(dict *d, void *key),功能类似于dictAddRaw,只不过需要返回指定的dictEntry
    1.调用dictAddRaw,返回值—>entry,参数返回值—>existing
    2.如果entry为空,返回existing;否则返回entry
 
4.static dictEntry *dictGenericDelete(dict *d, const void *key, int nofree)
    1.如果rehash标志位已经标记,则进行一次rehash
    2.先查找ht[0],如果找到对应key的dictEntry,删除并返回删除的dictEntry
    3.如果没有找到,则并且当前处于rehash途中,继续查找ht[1],找到后删除,并返回删除的dictEntry
    4.如果nofree为0,则需要释放key和value,否则不需要
    5.如果没有找到,直接返回NULL
 
5.dictEntry *dictUnlink(dict *ht, const void *key)
    删除指定key的dictEntry,但是不free空间。该函数主要用于在字典中摘掉该dictEntry,但该dictEntry的key和value将来还要用到,所以不释放空间。随后如果释放空间的话,需要调用dictFreeUnlinkedEntry函数
 
6.int _dictClear(dict *d, dictht *ht, void(callback)(void *))
    删除整个字典ht
7.void dictRelease(dict *d)
    对于ht[0]以及ht[1]分别调用_dictClear,去删除整个字典
 
8.dictEntry *dictFind(dict *d, const void *key)
    1.在ht[0]中查找与参数key匹配的dictEntry,如果找到直接返回。
    2.如果没有找到,看看是否正在rehash过程中,如果是,去找ht[1],如果在ht[1]中找到了,则返回该dictEntry,否则返回NULL
 
9.void *dictFetchValue(dict *d, const void *key)
    1.调用dictFind去查找指定key的dictEntry
    2.返回该dictEntry的value
 
10.dictEntry *dictNext(dictIterator *iter)
    1.如果iter->entry不为NULL,则返回iter->entry,并重置iter->entry以及iter->nextEntry
    2.当iter->entry为空,则判断iter->index是否大于ht->size,如果不是,则直接返回ht->table[iter->index];否则,令iter->index=0,返回ht[1]->table[iter->index]
 
11.void dictReleaseIterator(dictIterator *iter)
    1.iter->->iterators减1,即减少dict中表示指向自己的dictIterator个数
    2.释放iter空间
 
12.dictEntry *dictGetRandomKey(dict *d)
    1.如果正在rehash过程中,继续一步rehash
    2.根据是否正在rehash,采取不同的random策略。总体来说都是先hash出一个key,再根据每个key下挂载的桶的数量再做一遍hash,从而取得某个具体的桶。不同的是,如果正在rehash过程中,则在第一步hash的时候需要考虑ht[1]中的元素
 
13.unsigned long dictScan(dict *d, unsigned long v, dictScanFunction *fn, 
                                            dictScanBucketFunction* bucketfn, void *privdata)
    详见笔记《dictScan函数》
 
14.int dictRehash(dict *d, int n)
    执行rehash步骤,将ht[0]中的元素向ht[1]中进行rehash,共rehash n个桶。如果ht[0]中已经不存在元素,则删除ht[0]中空间,并将ht[0]指向ht[1],并返回0;否则返回1。无其他复杂逻辑
 
15.int dictRehashMilliseconds(dict *d, int ms)
    分批次执行dictRehash步骤,每次rehash 100个桶,如果当前总执行时间超过了ms毫秒,则退出函数,返回一共rehash了多少个桶
 
16.static int _dictKeyIndex(dict *d, const void *key, unsigned int hash, dictEntry **existing)
    在hash表中找到hash值等于参数hash,key等于参数key的桶
 
17.static int _dictExpandIfNeeded(dict *d)
    1.如果ht[0].size == 0, dictExpand(d, DICT_HT_INITIAL_SIZE)
    2.如果ht[0].used >= ht[0].size 并且 (used/size > 可resize比例 或者dict_can_resize标志位被置位),dictExpand(d, d->ht[0].used*2)
 
18.int dictExpand(dict *d, unsigned long size)
    找到比size大的最小2的n等幂,去扩容ht,无其他复杂逻辑 

猜你喜欢

转载自www.cnblogs.com/levy5307/p/9668624.html
今日推荐