shash出现在OVS的代码中,定义如下:
struct hmap_node {
size_t hash;
struct hmap_node * next;
};
struct shash_node {
struct hmap_node node;
char * name;
void * data;
}
struct hmap {
struct hmap_node ** buckets;
struct hmap_node * one;
size_t mask;
size_t n;
};
struct shash {
struct hmap map;
};
这是一个哈希表结构,hmap配合hmap_node完成哈希表的骨架,但不携带任何数据信息
shash_node是hamp_node的子类,携带数据信息。shash是hmap的子类,但不新增任何字段
hmap中:
bucket 指向哈希桶
one
mask 桶的长度,用以将散列值转化为桶索引
n 哈希表中结点的总数
之所以记录mask与n,是因为hmap本身是有扩容与缩容机制的
在hmap_insert中
static inline void
hmap_insert_at(struct hmap *hmap, struct hmap_node *node, size_t hash,
const char *where)
{
hmap_insert_fast(hmap, node, hash);
if (hmap->n / 2 > hmap->mask) {
hmap_expand_at(hmap, where);
}
}
就是通过hmap中结点数量如果大于桶位的两倍,就对桶进行扩容
one字段比较特殊,这个字段一般情况下是用不到的,只有一个场合会用到
/* Initializer for an immutable struct hmap 'HMAP' that contains 'N' nodes
* linked together starting at 'NODE'. The hmap only has a single chain of
* hmap_nodes, so 'N' should be small. */
#define HMAP_CONST(HMAP, N, NODE) { \
CONST_CAST(struct hmap_node **, &(HMAP)->one), NODE, 0, N }
这种情况下,整个hmap其实退化成了一个链表,链表表头由one字段保存,而buckets指向one字段。如下图:
也就是说,如果你正常的把hmap当哈希表用,是用不到one这个字段的,这个字段的值会恒为NULL
body,td { font-family: Consolas; font-size: 10pt }