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中添加一個元素

這裏要注意的是,不要搞混了用戶數據、用戶數據關鍵字和散列關鍵字

  • 用戶數據:未知,用戶自己定義的內存指針即可;
  • 用戶數據關鍵字:這是用戶數據中的某個成員,散列表根據它來進行散列;
  • 散列關鍵字:根據用戶數據關鍵字散列而得的數字。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章