nginx源码分析—hash结构ngx_hash_t(v1.0.4)

本文详细分析了nginx-1.0.4版本中的hash结构,包括ngx_hash_t、ngx_hash_init_t和ngx_hash_key_t等核心数据结构,以及hash初始化、查找等操作。通过一个实例展示了如何使用hash结构存储和查找url与ip的对应关系,揭示了nginx hash的设计与工作原理。
摘要由CSDN通过智能技术生成

本博客(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结构

 

nginxhash结构比其listarrayqueue等结构稍微复杂一些,下图是hash相关数据结构图。下面一一介绍。

 

1.1 ngx_hash_t结构

 

nginxhash结构为ngx_hash_thash元素结构为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) = 8sizeof(ngx_hash_elt_t) = 8。实际上,ngx_hash_elt_t结构中的name字段就是ngx_hash_key_t结构中的key。这在ngx_hash_init()函数中可以看到,请参考后续的分析。该结构在模块配置解析时经常使用。

 

1.2 ngx_hash_init_t结构

 

nginxhash初始化结构是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合法性验证等设计的数据结构,例如httpcore模块、map模块、referer模块、SSI filter模块等,此处不再讲述,将在后续的文章中介绍。

1.4 hash的逻辑结构

ngx_hash_init_t结构引用了ngx_pool_t结构,因此本文参考nginx-1.0.4源码分析—内存池结构ngx_pool_t及内存管理一文画出相关结构的逻辑图,如下。注:本文采用UML的方式画出该图。


评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值