//通配查找,匹配以.分隔的最后的字符串
//ngx_hash_find_wc_head的处理流程为:
//1,寻找字符串中,最后一个子串开始的位置
//2,计算最后这个子串的key值
//3,寻找这个key值对应的值域的指针
// 4,如果value值不是NULL,则
// 通过值域指针的后2bit判断,
// 该值域是00则表示该指针指向的是"example.com"或者"*.example.com"
// 该值域是01则表示该指针指向的仅仅是“.example.com”
//该值域是10则表示指向的是wildcard hash,允许"example.com"或者"*.example.com"
//该值域是11则表示指向的是wildcard hash ,仅仅允许 "*.example.com"
// 判断流程是: 先使用按位与 判断 第一位 是否为1,如果为1,则如果已经达到该字串的最开始位置(n==0),则判断第二位,
// 如果此时,第二位也是1,说明该值域是“*.example.com”,而实际上该字串的是“example.com”,肯定不符合,返回// NULL即可。如果第一位1,且也到达了字符串的开始位置(n==0),但是第二位不是1,则意味着允“example.com”
// ,返回值域的指针即可。 如果压根没有到达最开始的位置(n!=0),则说明应该返回需要继续查找的
// ngx_hash_wildcard_t的指针,该值即当前value,需要进行消除后两位的运算。之后,使用这个指针,进行递归调
// 用。而这个时候,需要查找的字符串,则是原始字符串去掉刚才查找的子字符串。
// 如果第一位不是1,即是0,(不需要进行判断,因为上述不符合,就是这种),则判断最后1位,如果是1,并且达到字串开// 始,返回NULL,即是"example.com",如果如果没有到达字符串开始,返回清0后2bit的value。
// 否则,也就是值是00 则返回value
// 5,如果value值是NULL,则返回hwt的value,即下一个指针。
void *
ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
{
void *value;
ngx_uint_t i, n, key;
#if 0
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wch:/"%*s/"", len, name);
#endif
n = len;
while (n) {
if (name[n - 1] == '.') {
break;
}
n--;
}
key = 0;
for (i = n; i < len; i++) {
key = ngx_hash(key, name[i]);
}
#if 0
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:/"%ui/"", key);
#endif
value = ngx_hash_find(&hwc->hash, key, &name[n], len - n);
#if 0
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:/"%p/"", value);
#endif
if (value) {
/*
* the 2 low bits of value have the special meaning:
* 00 - value is data pointer for both "example.com"
* and "*.example.com";
* 01 - value is data pointer for "*.example.com" only;
* 10 - value is pointer to wildcard hash allowing
* both "example.com" and "*.example.com";
* 11 - value is pointer to wildcard hash allowing
* "*.example.com" only.
*/
if ((uintptr_t) value & 2) {
if (n == 0) {
/* "example.com" */
if ((uintptr_t) value & 1) {
return NULL;
}
//value的值的后两位置0,返回给hwc
hwc = (ngx_hash_wildcard_t *)
((uintptr_t) value & (uintptr_t) ~3);
return hwc->value;
}
hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3);
value = ngx_hash_find_wc_head(hwc, name, n - 1);
if (value) {
return value;
}
return hwc->value;
}
if ((uintptr_t) value & 1) {
if (n == 0) {
/* "example.com" */
return NULL;
}
return (void *) ((uintptr_t) value & (uintptr_t) ~3);
}
return value;
}
return hwc->value;
}