core/ngx_hash.h头文件分析
本节我们讲述一下nginx中hash。nginx中hash有三种类型:
-
不带通配符的hash
-
带前向通配符的hash
-
带后向通配符的hash
注意: 不支持同时带有前向通配符与后向通配符的hash
1. ngx_hash_t数据结构
这里涉及到两个数据结构,我们先来讲述ngx_hash_elt_t
数据结构:
-
value
: 某个key对一个的值,即<key,value>中的value -
len
: name长度 -
name
: 占位符,某个要hash的数据(在nginx中表现为字符串),即<key,value>中的key
对于ngx_hash_t
数据结构:
-
buckets
: hash桶首地址 -
size
: hash桶个数
2. ngx_hash_wildcard_t数据结构
nginx支持带有通配符的散列表,用本结构代表前置或后置通配符散列表(注意: nginx不能同时包含在前与在后都有通配符的情况):
-
hash
: 基本散列表结构 -
value
: 指向用户数据
3. ngx_hash_key_t数据结构
-
key
: nginx的字符串结构,对应<key,value>结构中的key -
key_hash
: 由该key计算出的hash值 -
value
: 该key对应的value值
4. ngx_hash_combined_t数据结构
实际使用hash的时候,可能是精准匹配,也可能是前缀匹配,也可能是后缀匹配。因此Nginx封装了一个包含这三种情况的结构:
-
hash
: 精准匹配的散列表 -
wc_head
: 查询前置通配符的散列表 -
wc_tail
: 查询后置通配符的散列表
5. ngx_hash_init_t数据结构
ngx_hash_init_t
数据结构用于辅助我们建立起一个初始化的hash结构:
-
hash
: 指向普通的完全匹配散列表 -
key
: 散列方法 -
max_size
: hash表中桶的最大值,实际桶的个数存放在前面ngx_hash_t中的size字段中 -
bucket_size
: 每个bucket的空间,即ngx_hash_elt_t的空间大小 -
name
: hash表的名称(仅在错误日志中使用) -
pool
: 该hash结构从pool指向的内存池中分配 -
temp_pool
: 分配临时数据空间的内存池
6. ngx_hash_keys_arrays_t结构
在介绍ngx_hash_keys_arrays_t
数据结构之前,我们先介绍一下各宏定义:
-
NGX_HASH_SMALL
: 基于数组的Hash,用于指定当前hash的体量类别(小) -
NGX_HASH_LARGE
: 基于数组的Hash,用于指定当前hash的体量类别(大) -
NGX_HASH_LARGE_ASIZE
: 基于数组的Hash,用于指定ngx_hash_keys_arrays_t
结构中keys、dns_wc_head、dns_wc_tail数组的容量 -
NGX_HASH_LARGE_HSIZE
: 基于数组的Hash,用于指定桶的数量 -
NGX_HASH_WILDCARD_KEY
: hash key类型 -
NGX_HASH_READONLY_KEY
: hash key类型
下面再简要介绍ngx_hash_keys_arrays_t
数据结构:
-
hsize
: 用于指定桶大小 -
pool
: 该hash表所关联的内存池 -
temp_pool
: 临时内存池,下面的临时动态数组是由临时内存池分配的 -
keys
: 存放所有非通配符key的数组。数据类型为ngx_hash_key_t
-
key_hash
: 这是个二维数组,第一个维度代表的是bucket编号,那么keys_hash[i]中存放的是所有key求Hash后对hsize取模值为i的key列表。假设有3个key, 分别是key1、key2和key3,假设hash算出来以后对hsize去模的值都是i,那么这三个key就顺序存放在keys_hash[i][0]、keys_hash[i][1]、keys_hash[i][2]。该值在调用的过程中用来保存和检测是否有冲突的key值,也就是是否有重复 -
dns_wc_head
: 存放前向通配符key被处理完成以后的值。比如*.abc.com
被处理完成以后,变成com.abc.
被存放在此数组中。数据类型为ngx_hash_key_t
-
dns_wc_head_hash
: 这是一个二维数组。该值在调用的过程中用来保存和检测是否有冲突的key值,也就是是否有重复 -
dns_wc_tail
: 存放后向通配符key被处理完成以后的值。比如:mail.xxx.*
被处理完成以后,变成mail.xxx.
被存放在此数组中。数据类型为ngx_hash_key_t
-
dns_wc_tail_hash
: 这是一个二维数组。该值在调用的过程中用来保存和检测是否有冲突的key值,也就是是否有重复
7. ngx_table_elt_t数据结构
ngx_table_elt_t是一个key/value对,ngx_str_t类型的key、value成员分别存储的是名字、值字符串。
hash成员表明ngx_table_elt_t也可以是某个散列表数据结构中的成员。ngx_uint_t类型的hash成员可以在ngx_hash_t中更快地找到相同key的ngx_table_elt_t数据。lowcase_key指向的是全小写的key字符串。
ngx_table_elt_t是为HTTP头部量身定制的,其中key存储头部名称,value存储对应的值,lowcase_key是为了忽悠HTTP头部名称的大小写,hash用于快速检索到头部。比如:Content-Length: 1024
8. 相关函数声明