ngx_hash_t散列表(全匹配)
散列表槽的结构
typedef struct {
/* 指向用户定义元素数据的指针,如果当前ngx_hash_elt_t槽为空,则value=NULL */
void *value;
/* 元素关键字长度 */
u_short len;
/* 元素关键字首地址 */
u_char name[1];
} ngx_has_elt_t;
散列表结构
typedef struct {
/* 指向散列表的首地址,即第一个槽的地址 */
ngx_hash_elt_t **buckets;
/* 散列表中槽的个数 */
ngx_uint_t size;
};
散列表初始化所用的结构体
typedef struct {
/* 指向普通的全匹配散列表 */
ngx_hash_t *hash;
/* 用于初始化预添加元素的散列函数 */
ngx_hash_key_pt key;
/* 散列表中槽的最大数目 */
ngx_uint_t max_size;
/* 散列表中一个槽的空间大小,它限制了每个散列表元素关键字的最大值 */
ngx_uint_t bucket_size;
/* 散列表名称 */
char *name;
/* 内存池,分配散列表中所有的槽 */
ngx_pool_t *temp_pool;
} ngx_hash_init_t;
/* ngx_hash_init初始化函数参数中要用的结构体 *
typedef struct {
//元素关键字
ngx_str_t key;
//由散列方法计算出来的关键字
ngx_uint_t key_hash;
//指向实际的用户数据
void *value;
} ngx_hash_key_t;
/* 下面这个结构体又是用来获得上述ngx_hash_key_t的 */
typedef struct {
/* 下面的keys_hash、dns_wc_head_hash、dns_wc_tail_hash都是简易散列表,而hsize指明了散列表的槽的个数,
其简易散列方法也需要对hsize求余 */
ngx_uint_t hsize;
/* 内存池,分配永久性内存 */
ngx_pool_t *pool;
/* 临时内存池 */
ngx_pool_t *temp_pool;
/* 用动态数组保存不包含通配符关键字元素的ngx_hash_key_t */
ngx_array_t keys;
/* 一个极其简易的散列表,它以数组的形式保存hszie个ngx_array_t元素。在用户添加元素的过程中,会根据关键码
将用户的ngx_str_t类型的关键字添加到ngx_array_t中,这里用户元素的关键字都不带通配符。 */
ngx_array_t *keys_hash;
/* 用动态数组保存包含前置通配符关键字元素的ngx_hash_key_t */
ngx_array_t dns_wc_head;
/* 一个极其简易的散列表,它以数组的形式保存hszie个ngx_array_t元素。在用户添加元素的过程中,会根据关键码
将用户的ngx_str_t类型的关键字添加到ngx_array_t中,这里用户元素的关键字都带前置通配符。 */
ngx_array_t *dns_wc_head_hash;
/* 用动态数组保存包含后置通配符关键字元素的ngx_hash_key_t */
ngx_array_t dns_wc_tail;
/* 一个极其简易的散列表,它以数组的形式保存hszie个ngx_array_t元素。在用户添加元素的过程中,会根据关键码
将用户的ngx_str_t类型的关键字添加到ngx_array_t中,这里用户元素的关键字都带后置通配符。 */
ngx_array_t *dns_wc_tail_hash;
} ngx_hash_keys_arrays_t;
散列表的结构示意图
散列表常用函数
函数名 | 参数说明 | 执行意义 |
---|---|---|
ngx_int_t ngx_hash_init(ngx_hash_init_t *hinit,ngx_hash_key_t *names,ngx_uint_t nelts) | hinit是散列表初始化结构体的指针;names是数组的首地址,这是一个ngx_hash_key_t类型的数组,将要被添加如散列表;nelts是数组元素的个数 | 将names数组散列到散列表中 |
typedef ngx_uint_t (*ngx_hash_key_pt)(u_char *data,size_t len); | data是元素关键字的首地址;len是元素关键字长度 | 用来自定义散列方法 |
void *ngx_hash_find(ngx_hash_t *hash,ngx_uint_t key,u_char *name,size_t len) | hash是散列表结构体的指针;key是待查找元素的散列而得的关键字;name和len表示实际关键字的地址和长度 | 查询ngx_hash_elt_t中value所指向的用户数据 |
利用ngx_hash_keys_arrays_t获得ngx_hash_key_t数组,再交由ngx_hash_init函数,就能生成一个散列表。
ngx_hash_keys_arrays_t提供函数
函数名 | 参数说明 | 执行意义 |
---|---|---|
ngx_int_t ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha,ngx_uint_t type) | ha是要初始化的ngx_hash_keys_arrays_t指针;type:NGX_HASH_SMALL,初始化元素较少;NGX_HASH_LARGE,初始化元素较多 | 初始化结构体ngx_hash_keys_arrays_t,在想ha添加元素前必须调用 |
ngx_int_t ngx_hash_add_key(ngx_hash_keys_arrays_t *ha,ngx_str_t *key,void *value,ngx_uint_t flags) | ha同上;key是添加元素的关键字;value是对应的用户数据指针;flags:NGX_HASH_WILDCARD_KEY表示处理通配符;NGX_HASH_READONLY_KEY表示关键字不可更改;其他值表示不处理通配符,又允许修改关键字来散列 | 想ha中添加一个元素 |
这里要注意的是,不要搞混了用户数据、用户数据关键字和散列关键字
- 用户数据:未知,用户自己定义的内存指针即可;
- 用户数据关键字:这是用户数据中的某个成员,散列表根据它来进行散列;
- 散列关键字:根据用户数据关键字散列而得的数字。