本博客(http://blog.csdn.net/livelylittlefish )贴出作者(阿波)相关研究、学习内容所做的笔记,欢迎广大朋友指正!
Content
0.序
1.hash结构
1.1ngx_hash_t结构
1.2ngx_hash_init_t结构
1.3ngx_hash_key_t结构
1.4hash的逻辑结构
2.hash操作
2.1NGX_HASH_ELT_SIZE宏
2.2hash函数
2.3hash初始化
2.4hash查找
3.一个例子
3.1代码
3.2如何编译
3.3运行结果
3.3.1bucket_size=64字节
3.3.2bucket_size=256字节
4.小结
0. 序
本文继续介绍nginx的数据结构——hash结构。
链表实现文件:文件:./src/core/ngx_hash.h/.c。.表示nginx-1.0.4代码目录,本文为/usr/src/nginx-1.0.4。
1. hash结构
nginx的hash结构比其list、array、queue等结构稍微复杂一些,下图是hash相关数据结构图。下面一一介绍。
1.1 ngx_hash_t结构
nginx的hash结构为ngx_hash_t,hash元素结构为ngx_hash_elt_t,定义如下。
typedef struct { //hash元素结构
void *value; //value,即某个key对应的值,即<key,value>中的value
u_short len; //name长度
u_char name[1]; //某个要hash的数据(在nginx中表现为字符串),即<key,value>中的key
} ngx_hash_elt_t;
typedef struct { //hash结构
ngx_hash_elt_t **buckets; //hash桶(有size个桶)
ngx_uint_t size; //hash桶个数
} ngx_hash_t;
其中,sizeof(ngx_hash_t) = 8,sizeof(ngx_hash_elt_t) = 8。实际上,ngx_hash_elt_t结构中的name字段就是ngx_hash_key_t结构中的key。这在ngx_hash_init()函数中可以看到,请参考后续的分析。该结构在模块配置解析时经常使用。
1.2 ngx_hash_init_t结构
nginx的hash初始化结构是ngx_hash_init_t,用来将其相关数据封装起来作为参数传递给ngx_hash_init()或ngx_hash_wildcard_init()函数。这两个函数主要是在http相关模块中使用,例如ngx_http_server_names()函数(优化http Server Names),ngx_http_merge_types()函数(合并httptype),ngx_http_fastcgi_merge_loc_conf()函数(合并FastCGI Location Configuration)等函数或过程用到的参数、局部对象/变量等。这些内容将在后续的文章中讲述。
ngx_hash_init_t结构如下。sizeof(ngx_hash_init_t)=28。
typedef struct { //hash初始化结构
ngx_hash_t *hash; //指向待初始化的hash结构
ngx_hash_key_pt key; //hash函数指针
ngx_uint_t max_size; //bucket的最大个数
ngx_uint_t bucket_size; //每个bucket的空间
char *name; //该hash结构的名字(仅在错误日志中使用)
ngx_pool_t *pool; //该hash结构从pool指向的内存池中分配
ngx_pool_t *temp_pool; //分配临时数据空间的内存池
} ngx_hash_init_t;
1.3 ngx_hash_key_t结构
该结构也主要用来保存要hash的数据,即键-值对<key,value>,在实际使用中,一般将多个键-值对保存在ngx_hash_key_t结构的数组中,作为参数传给ngx_hash_init()或ngx_hash_wildcard_init()函数。其定义如下。
typedef struct { //hash key结构
ngx_str_t key; //key,为nginx的字符串结构
ngx_uint_t key_hash; //由该key计算出的hash值(通过hash函数如ngx_hash_key_lc())
void *value; //该key对应的值,组成一个键-值对<key,value>
} ngx_hash_key_t;
typedef struct { //字符串结构
size_t len; //字符串长度
u_char *data; //字符串内容
} ngx_str_t;
其中,sizeof(ngx_hash_key_t) = 16。一般在使用中,value指针可能指向静态数据区(例如全局数组、常量字符串)、堆区(例如动态分配的数据区用来保存value值)等。可参考本文后面的例子。
关于ngx_table_elt_t结构和ngx_hash_keys_arrays_t结构,因其对于hash结构本身没有太大作用,主要是为模块配置、referer合法性验证等设计的数据结构,例如http的core模块、map模块、referer模块、SSI filter模块等,此处不再讲述,将在后续的文章中介绍。
1.4 hash的逻辑结构
ngx_hash_init_t结构引用了ngx_pool_t结构,因此本文参考nginx-1.0.4源码分析—内存池结构ngx_pool_t及内存管理一文画出相关结构的逻辑图,如下。注:本文采用UML的方式画出该图。