ngx_hash_keys_array_init 在
./nginx-1.24.0/src/core/ngx_hash.c:683:ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
ngx_int_t
ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
{
ngx_uint_t asize;
if (type == NGX_HASH_SMALL) {
asize = 4;
ha->hsize = 107;
} else {
asize = NGX_HASH_LARGE_ASIZE;
ha->hsize = NGX_HASH_LARGE_HSIZE;
}
if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
if (ngx_array_init(&ha->dns_wc_head, ha->temp_pool, asize,
sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize,
sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize);
if (ha->keys_hash == NULL) {
return NGX_ERROR;
}
ha->dns_wc_head_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wc_head_hash == NULL) {
return NGX_ERROR;
}
ha->dns_wc_tail_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wc_tail_hash == NULL) {
return NGX_ERROR;
}
return NGX_OK;
}
函数作用
该函数用于初始化一个哈希表结构(ngx_hash_keys_arrays_t),用于存储键值对,并支持通配符匹配
根据传入的 type 参数,选择不同的初始配置,以优化内存使用和查找效率。
if (type == NGX_HASH_SMALL) {
asize = 4;
ha->hsize = 107;
} else {
asize = NGX_HASH_LARGE_ASIZE;
ha->hsize = NGX_HASH_LARGE_HSIZE;
}
if (type == NGX_HASH_SMALL)
判断哈希表类型是否为 NGX_HASH_SMALL。
根据传入的 type 参数决定哈希表的配置。
NGX_HASH_SMALL 表示配置一个小规模哈希表,适用于键数量较少的场景。
通过条件分支选择不同的初始配置(小或大),平衡内存使用和性能。
asize = 4;
设置初始数组的大小(asize)为 4
asize 是动态数组(如 ngx_array_t)的初始容量。
当 type 是 NGX_HASH_SMALL 时,初始数组大小设为 4
ha->hsize = 107;
- 作用:设置哈希表的桶数量(hsize)为 107。
- 逻辑:
- hsize 是哈希表的大小,即哈希桶的数量。
- 当 type 是 NGX_HASH_SMALL 时,哈希表大小设为 107。
- 意义:
- 质数选择:107 是一个质数,有助于均匀分布哈希值,减少哈希冲突的概率。
- 小规模适配:107 是一个适中的质数,适合存储少量键(如几十个键),同时保持查找效率。
4. asize = NGX_HASH_LARGE_ASIZE;
- 作用:设置初始数组的大小(asize)为宏定义的 NGX_HASH_LARGE_ASIZE。
- 逻辑:
- 当 `type` 是 `NGX_HASH_LARGE` 时,使用预定义的宏值
- 意义:
- 适应大规模数据:初始数组容量更大,减少频繁扩容的开销。
- 宏定义灵活性:通过宏(如 `NGX_HASH_LARGE_ASIZE`)统一配置,便于后续调整。
5. ha->hsize = NGX_HASH_LARGE_HSIZE;
- 作用:设置哈希表的桶数量(`hsize`)为宏定义的 `NGX_HASH_LARGE_HSIZE`。
if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
这段代码的作用是初始化动态数组(`ngx_array_t`),用于存储普通键,是构建哈希表的关键步骤。
`ha->keys` 是一个 `ngx_array_t` 类型的动态数组,用于暂存后续需要添加到哈希表中的普通键
通过 `ha->temp_pool`(内存池)分配内存,
if (ngx_array_init(&ha->dns_wc_head, ha->temp_pool, asize,
sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
调用 `ngx_array_init` 函数初始化动态数组,并检查返回值是否为成功状态。
- 若返回值 `!= NGX_OK`(如内存分配失败),则触发错误处理逻辑。
dns_wc_head 专门用于存储前缀通配符键
通配符类型 :dns_wc_head
存储形如 *.example.com
的前缀通配符键 (即通配符在左侧的域名)。
与普通键分离 :与普通键(keys
)和后缀通配符键(dns_wc_tail
,如 example.com.*
)分开存储,避免匹配时的干扰。
前缀通配符(*.example.com
)匹配所有子域名(如 a.example.com
、b.example.com
)
命名解析
dns
含义 :表示与 DNS(Domain Name System) 相关。
wc
head
英文全称
完整含义 :DNS Wildcard Head
即“DNS 前缀通配符”,明确表示该结构用于存储和处理以通配符开头的域名 (前缀通配符)。
if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize,
sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
调用 `ngx_array_init` 初始化动态数组,并检查返回值是否为成功状态。
- 存储后缀通配符键:该数组用于暂存所有后缀通配符键(如 `example.com.*`),与普通键(`keys`)和前缀通配符键(`dns_wc_head`)分离。
ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize);
if (ha->keys_hash == NULL) {
return NGX_ERROR;
}
ha->dns_wc_head_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wc_head_hash == NULL) {
return NGX_ERROR;
}
ha->dns_wc_tail_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wc_tail_hash == NULL) {
return NGX_ERROR;
}
ha->keys_hash = ngx_pcalloc(...)
- 作用:为普通键的哈希表(`keys_hash`)分配内存。
- 哈希表结构初始化:每个哈希桶(`ngx_array_t`)用于存储具有相同哈希值的普通键(如 `example.com`)。
ha->dns_wc_head_hash = ngx_pcalloc(...)
- 作用:为前缀通配符键的哈希表(`dns_wc_head_hash`)分配内存。
- 逻辑:
- 分配 `ha->hsize` 个 `ngx_array_t` 的内存空间,每个桶存储前缀通配符键(如 `*.example.com`)。
ha->dns_wc_tail_hash = ngx_pcalloc(...)
作用:为后缀通配符键的哈希表(dns_wc_tail_hash)分配内存。
- 逻辑:
- 分配 `ha->hsize` 个 `ngx_array_t` 的内存空间,每个桶存储后缀通配符键(如 `example.com.*`)。
return NGX_OK;
返回 表示成功