哈希表

 
【hash字典】

 

    1. typedef struct dict {  
    2.     dictType *type;//上边的type,为不同数据类型hash使用的回调函数,  
    3.     void *privdata;  //传给类型特定函数的可选参数
    4.     dictht ht[2]; //使用的两个hash表,主要是用来旧的到新的转换  
    5.     int rehashidx; /* rehashing not in progress if rehashidx == -1 */是否在使用  
    6.     int iterators; /* number of iterators currently running */数量  
    7. } dict;  
 
 
 

【hash表】

 
    1. typedef struct dictht {  
    2.     dictEntry **table;  
    3.     unsigned long size;  
    4.     unsigned long sizemask;  
    5.     unsigned long used;  
    6. } dictht;  

 

table 属性组成了一个数组,数组里带有节点指针,用作链表。

size 、 sizemask 和 used 这三个属性初看上去让人有点头晕,实际上,它们分别代表的是:

size :桶的数量,也即是, table 数组的大小。

sizemask :这个值通过 size – 1 计算出来,给定 key 的哈希值计算出来之后,就会和这个数值进行 & 操作,决定元素被放到 table 数组的那一个位置上。

used :这个值代表目前哈希表中元素的数量,也即是哈希表总共保存了多少 dictEntry 结构。

 

【节点项】

 

 

 

typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;

 

 

 

 

【hash表迭代器】

 
    1. typedef struct dictIterator {  
    2.     dict *d;  
    3.     int table, index, safe;  
    4.     dictEntry *entry, *nextEntry;  
    5.     long long fingerprint; /* unsafe iterator fingerprint for misuse detection */  
    6. } dictIterator;  

 

【hash算法回调函数】

 
    1. typedef struct dictType {  
    2.     unsigned int (*hashFunction)(const void *key);  
    3.     void *(*keyDup)(void *privdata, const void *key);  
    4.     void *(*valDup)(void *privdata, const void *obj);  
    5.     int (*keyCompare)(void *privdata, const void *key1, const void *key2);  
    6.     void (*keyDestructor)(void *privdata, void *key);  
    7.     void (*valDestructor)(void *privdata, void *obj);  
    8. } dictType;  
 

该数据结构,用来指定hash算法的一些回调函数,比如key 比较,复制等。

 
dictEntry *dictAddRaw(dict *d, void *key)  
{  
    int index;  
    dictEntry *entry;  
    dictht *ht;
 
    if (dictIsRehashing(d)) _dictRehashStep(d);  
 
    /* Get the index of the new element, or -1 if
     * the element already exists. */  
    if ((index = _dictKeyIndex(d, key)) == -1)  
        return NULL;  
 
    /* Allocate the memory and store the new entry */  
    ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];  
    entry = zmalloc(sizeof(*entry));  
    entry->next = ht->table[index];  
    ht->table[index] = entry;  
    ht->used++;  
 
    /* Set the hash entry fields. */  
    dictSetKey(d, entry, key);  
    return entry;  
}  

 

原文地址:https://www.cnblogs.com/lsx1993/p/4614884.html