天天看點

Nginx 基礎資料結構

學習《深入了解Nginx子產品開發與架構解析》的記錄

整型

typedef intptr_t    ngx_int_t;
typedef uintptr_t   ngx_uint_t;
typedef intptr_t    ngx_flag_t;
           

可以看到,ngx_int_t實際上是intptr_t,而intptr_t的定義在/usr/include/stdint.h:

/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int        intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned long int   uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int         intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned int        uintptr_t;
#endif
           

在64位機器上,intptr_t是long int,否則是int。

疑問:intptr_t從名字上是儲存指針用的,實際上是long int 或 int?

字元串

typedef struct {
    size_t      len; // 字元串不一定以\0結尾,是以需要len給出字元串長度
    u_char     *data;
} ngx_str_t;

typedef struct {
    ngx_str_t   key;
    ngx_str_t   value;
} ngx_keyval_t;

typedef struct {
    unsigned    len:;

    unsigned    valid:;
    unsigned    no_cacheable:;
    unsigned    not_found:;
    unsigned    escape:;

    u_char     *data;
} ngx_variable_value_t;
           

連結清單

ngx_list_t使用頻繁,如HTTP頭部就是用ngx_list_t存儲的。

節點定義:

typedef struct ngx_list_part_s  ngx_list_part_t;

struct ngx_list_part_s {
    void             *elts; // 指向數組的起始位址
    ngx_uint_t        nelts;// 數組中已經使用了多少元素
    ngx_list_part_t  *next; // 下一個節點
};
           

節點中的資料域是一個指針(void *)指向一塊連續的記憶體。這樣連結清單中存放的元素沒有固定的資料類型,很靈活。

連結清單定義:

typedef struct {
    ngx_list_part_t  *last; // 指向最後一個節點
    ngx_list_part_t   part; // "指向"第一個節點
    size_t            size; // 每個節點中,一個數組元素占用空間的大小限制,即elts指向數組中每個元素的大小
    ngx_uint_t        nalloc;// 每個節點中數組的元素個數
    ngx_pool_t       *pool; // 記憶體池
} ngx_list_t;
           
Nginx 基礎資料結構

根據這個記憶體分布圖,可以知道連結清單的所有元素都由pool來分派,pool是一塊連續的記憶體。是以周遊這個連結清單的方式是這樣的:

/*
 *
 *  the iteration through the list:
 *
 *  part = &list.part; // part指向連結清單的第一個節點
 *  data = part->elts; // data指向該節點所指向的數組空間
 *
 *  for (i =  ;; i++) { // 通路數組中的每一個元素
 *
 *      if (i >= part->nelts) { // nelts表示數組中的元素個數,當達到它時,表示該節點中的所有元素已經周遊完
 *          if (part->next == NULL) { // 沒有下一個節點元素,表示連結清單周遊完
 *              break;
 *          }
 *          
 *          // 準備周遊連結清單中下一個節點中的數組
 *          part = part->next;
 *          data = part->elts;
 *          i = ;
 *      }
 *
 *      // 通路一個數組元素
 *      ...  data[i] ...
 *
 *  }
 */
           

ngx_table_elt_t

// src/core/ngx_hash.h
typedef struct {
    ngx_uint_t        hash;
    ngx_str_t         key;
    ngx_str_t         value;
    u_char           *lowcase_key;
} ngx_table_elt_t;
           

用于表示HTTP頭部資訊。如key是Content-Length,value是1024。

繼續閱讀