Nginx學習筆記(三) Nginx基本數據結構


Nginx基本數據結構

  話說學習一種編程語言,例如C語言,我們首先學的也是數據結構,這是以后開發程序的關鍵。為了更好更方便的開發Nginx,Nginx自己實現了很多適合nginx的數據結構。

Nginx中的數組

  ngx_array_s是Nginx中的數組,原型為ngx_array_t。

typedef struct {
    void        *elts;           //指向數據的指針
    ngx_uint_t   nelts;          //數組中元素的個數
    size_t       size;       //數組中每個元素的大小
    ngx_uint_t   nalloc;      //數據容量
    ngx_pool_t  *pool;       //用來分配內存的內存池
} ngx_array_t;

  這里的數組已經遠遠超出了C語言中數據的概念,類似於Vector。

  具體操作參見源碼。

Nginx中的隊列

  ngx_queue_t是Nginx中的隊列元素,原型為ngx_queue_s.

struct ngx_queue_s {
    ngx_queue_t  *prev;
    ngx_queue_t  *next;
};

  具體操作參見源碼。

Nginx中的鏈表

  ngx_list_t是Nginx中的list結構。

typedef struct {
    ngx_list_part_t  *last;    //鏈表最后節點
    ngx_list_part_t   part;   //鏈表首部節點
    size_t            size;    //鏈表中存放具體元素的所需內存大小
    ngx_uint_t        nalloc;   //每個節點所含固定大小的數組容量
    ngx_pool_t       *pool;       //用於分配內存的內存池
} ngx_list_t;

  ngx_list_part_t是Nginx中的List的元素結構。

struct ngx_list_part_s {
    void             *elts;    //指向數據
    ngx_uint_t        nelts;    //長度
    ngx_list_part_t  *next;
};

  具體操作參見源碼。

Nginx中的string--ngx_str_t

  ngx_str_t為Nginx自身實現的string結構,與c中的字符串不同。

typedef struct {
    size_t      len;   //字符串長度
    u_char     *data;  //指向字符串的指針
} ngx_str_t;

   ngx_str_t包括兩部分,一部分是字符串的長度,另外一部分是數據。注意:這里的數據是指向字符的一個指針,且這個字符串不是以“0”結尾,是通過長度來控制的。使用指針,省去了拷貝所占用的內存空間。

  其他Nginx-String的操作可以看Nginx源碼,還是蠻清晰的。

Ngnix中的內存分配和釋放

  在Ngnix中負責內存分配和釋放的結構體為ngx_pool_t,它的原型為ngx_pool_s。

struct ngx_pool_s {
    ngx_pool_data_t       d;
    size_t                max;
    ngx_pool_t           *current;
    ngx_chain_t          *chain;
    ngx_pool_large_t     *large;
    ngx_pool_cleanup_t   *cleanup;
    ngx_log_t            *log;
};

  具體操作參考源碼。

Nginx中的Hash表

  ngx_hash_t是Nginx中的hash表。

typedef struct {
    ngx_hash_elt_t  **buckets;
    ngx_uint_t        size;
} ngx_hash_t;

  其中ngx_hash_elt_t為數據。

typedef struct {
    void             *value;    //數據 value         
    u_short           len;         //數據長度?
    u_char            name[1];   //key
} ngx_hash_elt_t;

  但是ngx_hash_t的實現又有其幾個顯著的特點:

  1. ngx_hash_t不像其他的hash表的實現,可以插入刪除元素,它只能一次初始化,就構建起整個hash表以后,既不能再刪除,也不能在插入元素了。
  2. ngx_hash_t的開鏈並不是真的開了一個鏈表,實際上是開了一段連續的存儲空間,幾乎可以看做是一個數組。這是因為ngx_hash_t在初始化的時候,會經歷一次預計算的過程,提前把每個桶里面會有多少元素放進去給計算出來,這樣就提前知道每個桶的大小了。那么就不需要使用鏈表,一段連續的存儲空間就足夠了。這也從一定程度上節省了內存的使用。

  實際上ngx_hash_t的使用是非常簡單,首先是初始化,然后就可以在里面進行查找了。

Nginx中的紅黑樹

  ngx_rbtree_node_s是Nginx中的紅黑樹節點。

struct ngx_rbtree_node_s {
    ngx_rbtree_key_t       key;
    ngx_rbtree_node_t     *left;
    ngx_rbtree_node_t     *right;
    ngx_rbtree_node_t     *parent;
    u_char                 color;
    u_char                 data;
};

  ngx_rbtree_s是Nginx中的紅黑樹。

struct ngx_rbtree_s {
    ngx_rbtree_node_t     *root;
    ngx_rbtree_node_t     *sentinel;
    ngx_rbtree_insert_pt   insert;
};

  具體操作參見源碼。

 待添加(以后再看)

ngx_time_t

ngx_slab_

ngx_chain_t

ngx_hash_key_arrays_t

ngx_hash_combined_t

ngx_hash_wildcard_t

ngx_buf_t


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM