/* A hash map node, to be embedded inside the data structure being mapped. */ struct hmap_node { size_t hash; /* Hash value. */ struct hmap_node *next; /* Next in linked list. */ }; ``` 每一個hmap_node 中包括哈希值和指針next,具備類似hash值得節點會經過next域串聯起來(注意:全部hash值都是不一樣的,只是在一個桶中連接的結點hash值具備某種可追蹤性or局部性,即與mask相掩以後值相同),能夠縮短查找時間。 # 2,hash map
/* A hash map. */ struct hmap { struct hmap_node *buckets; / Must point to 'one' iff 'mask' == 0. */ struct hmap_node *one; size_t mask; size_t n; }; ```node
容器hmap中:
buckets 是一個pointer to struct hmap_node * , 能夠理解爲一個 指針數組,其中每一項指向具備某一塊hash值得鏈表頭結點。 mask域的存在使得能夠直接獲得對應的桶,即 buckets[node->hash & hmap->mask] ;在一個映射表rehash(能夠理解爲超過了裝載因子限制,須要從新分配空間)以前,能夠達到的最大節點數是 mask*2+1 (loadfactor是0.5 ?).數組
static inline void hmap_insert_fast(struct hmap *hmap, struct hmap_node *node, size_t hash) { struct hmap_node **bucket = &hmap->buckets[hash & hmap->mask]; node->hash = hash; node->next = *bucket; *bucket = node; hmap->n++; }``` 2.同上,可是會擴容,爲了優化查詢性能。
static inline void hmap_insert(struct hmap *hmap, struct hmap_node *node, size_t hash){ hmap_insert_fast(hmap, node, hash); if (hmap->n / 2 > hmap->mask) { hmap_expand(hmap); } }app
void hmap_expand(struct hmap *hmap){ size_t new_mask = calc_mask(hmap->n); //更新掩碼,沒看懂。 if (new_mask > hmap->mask) { COVERAGE_INC(hmap_expand); resize(hmap, new_mask); } }```ide
3.移除某個結點性能
static inline void hmap_remove(struct hmap *hmap, struct hmap_node *node){ struct hmap_node **bucket = &hmap->buckets[node->hash & hmap->mask]; while (*bucket != node) { bucket = &(*bucket)->next; } *bucket = node->next; //最終*bucket指向 node結點,怎麼感受和前面脫節了?? hmap->n--; }``` 4.而且由hmap衍生出的具體結構體也不少,好比字符串到無符號整型的映射
struct simap { struct hmap map; /* Contains "struct simap_node"s. */ };優化
struct simap_node { struct hmap_node node; /* In struct simap's 'map' hmap. */ char *name; unsigned int data; }; ```指針