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中添加一個元素 |
這裏要注意的是,不要搞混了用戶數據、用戶數據關鍵字和散列關鍵字
- 用戶數據:未知,用戶自己定義的內存指針即可;
- 用戶數據關鍵字:這是用戶數據中的某個成員,散列表根據它來進行散列;
- 散列關鍵字:根據用戶數據關鍵字散列而得的數字。