理解 Nginx 源码之七 哈希表结构 ngx

概述

关于哈希表的基本知识在前面的文章《数据结构-哈希表》已作介绍。哈希表结合了数组和链表的特点,使其寻址、插入以及删除操作更加方便。哈希表的过程是将关键字通过某种哈希函数映射到相应的哈希表位置,即对应的哈希值所在哈希表的位置。但是会出现多个关键字映射相同位置的情况导致冲突问题,为了解决这种情况,哈希表使用两个可选择的方法:

拉链法开放寻址法

Nginx 的哈希表中使用开放寻址来解决冲突问题,为了处理字符串,Nginx 还实现了支持通配符操作的相关函数,下面对 Nginx 中哈希表的源码进行分析。源码文件:src/core/ngx_hash.h/.c。

哈希表结构

**ngx_hash_elt_t 结构 **

哈希表中关键字元素的结构 ngx_hash_elt_t,哈希表元素结构采用 键-值 形式,即 。其定义如下:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

ngx_hash_t 结构

哈希表基本结构 ngx_hash_t,其结构定义如下

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

元素结构图以及基本哈希结构图如下所示:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

**ngx_hash_init_t 初始化结构 **

哈希初始化结构 ngx_hash_init_t,Nginx 的 hash 初始化结构是 ngx_hash_init_t,用来将其相关数据封装起来作为参数传递给ngx_hash_init(),其定义如下:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

哈希元素数据 ngx_hash_key_t,该结构也主要用来保存要 hash 的数据,即键-值对,在实际使用中,一般将多个键-值对保存在 ngx_hash_key_t 结构的数组中,作为参数传给ngx_hash_init()。其定义如下:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

哈希操作

哈希操作包括初始化函数、查找函数;其中初始化函数是 Nginx 中哈希表比较重要的函数,由于 Nginx 的 hash 表是静态只读的,即不能在运行时动态添加新元素的,一切的结构和数据都在配置初始化的时候就已经规划完毕。

哈希函数

哈希表中使用哈希函数把用户数据映射到哈希表对应的位置中,下面是 Nginx 哈希函数的定义:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

哈希初始化函数

hash 初始化由 ngx_hash_init() 函数完成,其 names 参数是 ngx_hash_key_t 结构的数组,即键-值对 数组,nelts 表示该数组元素的个数。该函数初始化的结果就是将 names 数组保存的键-值对,通过 hash 的方式将其存入相应的一个或多个 hash 桶(即代码中的 buckets )中。hash 桶里面存放的是 ngx_hash_elt_t 结构的指针(hash元素指针),该指针指向一个基本连续的数据区。该数据区中存放的是经 hash 之后的键-值对

,即 ngx_hash_elt_t 结构中的字段 。每一个这样的数据区存放的键-值对可以是一个或多个。其定义如下:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

哈希查找函数

hash 查找操作由 ngx_hash_find() 函数完成,查找时由 key 直接计算所在的 bucket,该 bucket 中保存其所在 ngx_hash_elt_t 数据区的起始地址;然后根据长度判断并用 name 内容匹配,匹配成功,其 ngx_hash_elt_t 结构的 value 字段即是所求。其定义如下:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

测试程序:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

main函数

理解 Nginx 源码之七 哈希表结构 ngx_hash_t

输出结果:

理解 Nginx 源码之七 哈希表结构 ngx_hash_t


分享到:


相關文章: