/* 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; }; ```指针