ngx_hash散列表

ngx_hash_t散列表(全匹配)

散列表槽的结构

typedef struct {
    /* 指向用户定义元素数据的指针,如果当前ngx_hash_elt_t槽为空,则value=NULL */
    void            *value;
    /* 元素关键字长度 */
    u_short     len;
    /* 元素关键字首地址 */
    u_char          name[1];
} ngx_has_elt_t;

散列表结构

typedef struct {
    /* 指向散列表的首地址,即第一个槽的地址 */
    ngx_hash_elt_t  **buckets;
    /* 散列表中槽的个数 */
    ngx_uint_t      size;
};

散列表初始化所用的结构体

typedef struct {
    /* 指向普通的全匹配散列表 */
    ngx_hash_t      *hash;
    /* 用于初始化预添加元素的散列函数 */
    ngx_hash_key_pt key;
    /* 散列表中槽的最大数目 */
    ngx_uint_t      max_size;
    /* 散列表中一个槽的空间大小,它限制了每个散列表元素关键字的最大值 */
    ngx_uint_t      bucket_size;
    /* 散列表名称 */
    char                *name;
    /* 内存池,分配散列表中所有的槽 */
    ngx_pool_t      *temp_pool;
} ngx_hash_init_t;

/* ngx_hash_init初始化函数参数中要用的结构体 *
typedef struct {
    //元素关键字
    ngx_str_t           key;
    //由散列方法计算出来的关键字
    ngx_uint_t      key_hash;
    //指向实际的用户数据
    void                *value;
} ngx_hash_key_t;

/* 下面这个结构体又是用来获得上述ngx_hash_key_t的 */
typedef struct {
    /* 下面的keys_hash、dns_wc_head_hash、dns_wc_tail_hash都是简易散列表,而hsize指明了散列表的槽的个数,
    其简易散列方法也需要对hsize求余 */
    ngx_uint_t      hsize;
    /* 内存池,分配永久性内存 */
    ngx_pool_t      *pool;
    /* 临时内存池 */
    ngx_pool_t      *temp_pool;

    /* 用动态数组保存不包含通配符关键字元素的ngx_hash_key_t */
    ngx_array_t     keys;
    /* 一个极其简易的散列表,它以数组的形式保存hszie个ngx_array_t元素。在用户添加元素的过程中,会根据关键码
    将用户的ngx_str_t类型的关键字添加到ngx_array_t中,这里用户元素的关键字都不带通配符。 */
    ngx_array_t     *keys_hash;

    /* 用动态数组保存包含前置通配符关键字元素的ngx_hash_key_t */
    ngx_array_t     dns_wc_head;
    /* 一个极其简易的散列表,它以数组的形式保存hszie个ngx_array_t元素。在用户添加元素的过程中,会根据关键码
    将用户的ngx_str_t类型的关键字添加到ngx_array_t中,这里用户元素的关键字都带前置通配符。 */
    ngx_array_t     *dns_wc_head_hash;

    /* 用动态数组保存包含后置通配符关键字元素的ngx_hash_key_t */
    ngx_array_t     dns_wc_tail;
    /* 一个极其简易的散列表,它以数组的形式保存hszie个ngx_array_t元素。在用户添加元素的过程中,会根据关键码
    将用户的ngx_str_t类型的关键字添加到ngx_array_t中,这里用户元素的关键字都带后置通配符。 */
    ngx_array_t     *dns_wc_tail_hash;
} ngx_hash_keys_arrays_t;

散列表的结构示意图

散列表的结构示意图

散列表常用函数

函数名 参数说明 执行意义
ngx_int_t ngx_hash_init(ngx_hash_init_t *hinit,ngx_hash_key_t *names,ngx_uint_t nelts) hinit是散列表初始化结构体的指针;names是数组的首地址,这是一个ngx_hash_key_t类型的数组,将要被添加如散列表;nelts是数组元素的个数 将names数组散列到散列表中
typedef ngx_uint_t (*ngx_hash_key_pt)(u_char *data,size_t len); data是元素关键字的首地址;len是元素关键字长度 用来自定义散列方法
void *ngx_hash_find(ngx_hash_t *hash,ngx_uint_t key,u_char *name,size_t len) hash是散列表结构体的指针;key是待查找元素的散列而得的关键字;name和len表示实际关键字的地址和长度 查询ngx_hash_elt_t中value所指向的用户数据

利用ngx_hash_keys_arrays_t获得ngx_hash_key_t数组,再交由ngx_hash_init函数,就能生成一个散列表。



ngx_hash_keys_arrays_t提供函数

函数名 参数说明 执行意义
ngx_int_t ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha,ngx_uint_t type) ha是要初始化的ngx_hash_keys_arrays_t指针;type:NGX_HASH_SMALL,初始化元素较少;NGX_HASH_LARGE,初始化元素较多 初始化结构体ngx_hash_keys_arrays_t,在想ha添加元素前必须调用
ngx_int_t ngx_hash_add_key(ngx_hash_keys_arrays_t *ha,ngx_str_t *key,void *value,ngx_uint_t flags) ha同上;key是添加元素的关键字;value是对应的用户数据指针;flags:NGX_HASH_WILDCARD_KEY表示处理通配符;NGX_HASH_READONLY_KEY表示关键字不可更改;其他值表示不处理通配符,又允许修改关键字来散列 想ha中添加一个元素

这里要注意的是,不要搞混了用户数据、用户数据关键字和散列关键字

  • 用户数据:未知,用户自己定义的内存指针即可;
  • 用户数据关键字:这是用户数据中的某个成员,散列表根据它来进行散列;
  • 散列关键字:根据用户数据关键字散列而得的数字。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章