nginx的基本数据结构

ngx_str_t
源码文件:ngx_string.h|c
定义:
struct  ngx_str_s {
  size_t      len;//字符串长度
  u_char     *data;//字符串起始地址
} ngx_str_t;
说明:
ngx_str_t是nginx使用的字符串类型,ngx_str_t用len成员来表示字符串的长度,c标准库中的很多字符串函数不能用于ngx_str_t,因此nginx实现了很多用于ngx_str_t的函数

常用函数/宏:
ngx_string(str):给一个ngx_str_t变量赋值
ngx_null_string:用于初始化一个ngx_str_t变量
ngx_str_set(str, text):用text对str变量进行赋值,这里text只能字符串字面值常量
ngx_str_null(str):重置str变量


ngx_buf_t,ngx_chain_t
源码文件:ngx_buf.h|c
定义:
struct ngx_buf_s {
  u_char *pos;//数据起始地址
  u_char *last;//数据结束地址
  off_t file_pos;//数据在文件中的起始位置偏移量
  off_t file_last;//数据在文件中的结束位置偏移量
  u_char *start;//buffer在内存中的起始地址
  u_char *end;//buffer在内存中的结束地址
  ngx_buf_tag_t tag;//可以是任何数据
  ngx_file_t *file;//如果buf内容在文件中,那么存储的是文件的信息
  ngx_buf_t *shadow;//指向另外一个buf,该buf与这个buf实际指向同一个内存对象
  unsigned temporary:1;//1代表该buf的数据是可以更改的
  unsigned memory:1;//代表该buf数据在内存中,且不可修改
  unsigned mmap:1;//代表该buf是文件通过内存映射到内存中,不可更改
  unsigned recycled:1;//代表是可重复利用的,即可以释放的
  unsigned in_file:1;//代表该buf的内容在文件中
  unsigned flush:1;
  unsigned sync:1;
  unsigned last_buf:1;//该buf在一系列链中是最后一个
  unsigned last_in_chain:1;//该buf是所在链的最后一个节点
  unsigned last_shadow:1;
  unsigned temp_file:1;
  int num;
}

说明:nginx中用作数据缓冲区的基本结构
常用函数/宏:
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
说明:从内存池中创建一个容量为size的临时buf,该buf的内容是可以修改的

ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool)
说明:从内存池中创建一个链表。如果内存池中已经有可用链表对象,则直接返回该对象,并且将内存池的chain成员指向下一个结点;如果没有可用对象,则直接从内存池获取一块大小为ngx_chain_t的内存,并将首地址返回。

ngx_chain_t *ngx_alloc_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
说明:创建包含若干buf结点的chain,buf结点的数量和容量由bufs参数决定

ngx_int_t ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t *chain, ngx_chain_t *in)
说明;链表添加。将in链的buf加在chain链的末尾

ngx_chain_t *ngx_chain_get_free_buf(ngx_pool_t *pool, ngx_chain_t **free)
说明:从buf链获取空闲的buf。如果free所指向的链中有空闲的buf,就将该空闲buf的地址返回,并且将free指向下一个空闲的buf;如果free中没有空闲buf,则从内存池中申请新的chain并返回。

void ngx_chain_update_chains(ngx_pool_t *pool, ngx_chain_t **free, ngx_chain_t **busy, ngx_chain_t **out, ngx_buf_tag_t tag)
说明:更新chain。
1.  如果out不为空,就将out加在busy的末尾,然后将out置空。
2.  遍历busy的所有节点,如果节点buf的大小不为0(即还未用完)就结束遍历,否则继续下一步。
3.  如果节点buf的tag成员与tag参数不匹配,就将busy指向下一个结点,并且将当前节点插入到pool的chain成员头部,然后继续遍历busy,否则进行下一步
4.  将节点的buf重置(pos,last都指向start),然后把节点插入到free链表的头部

ngx_chain_t *ngx_chain_update_sent(ngx_chain_t *in, off_t sent)
说明:更新chain,依次把in的buf的可用内存区更新,如果sent大于可用内存,就将可用内存置为0,并把sent减去可用内存大小,然后跳到下一个结点,直到sent为0或者in的所有节点都被更新完

ngx_array_t
源码文件:ngx_array.h|c
定义:
typedef struct {
  void *elts;//指向元素首地址
  ngx_uint_t nelts;//当前元素数量
  size_t size;//元素大小
  ngx_uint_t nalloc;//数组容量
  ngx_pool_t *pool;//内存池指针
};

说明:
常用函数/宏:
ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
说明:创建包含n个元素,每个元素大小为size的数组

void ngx_array_destroy(ngx_array_t *a)
说明:销毁数组。该函数只在数组是从内存池分配出去的最后一块内存时才会释放数组及元素所在内存块,否则将什么也不做。释放的方法就是把pool->d的last成员减去数组元素以及数组结构体本身所占内存的大小,以此扩大内存池可用空间大小。

void *ngx_array_push(ngx_array_t *a)
说明:向数组中追加一个元素。如果数组未满,则直接从数组的数据内存块中取。否则,如果数组的数据块是内存池分配的最近一块内存(即数据块的最后一个字节的地址等于pool->d.last)且内存池剩余内存块大于数组元素的大小,就直接从内存池中获取,并将数组的nalloc加1,否则就从内存池中重新申请一块大小为原数组大小两倍的内存块,将原数组内存块拷贝到新数组中,并将数组的elts指向新的内存块,nalloc翻倍。这里需要注意的是,原来的内存块此时并未释放,这样会造成内存的浪费,所以创建数组的时候尽量预估好数组的容量,避免浪费内存。

void *ngx_array_push_n(ngx_array_t *a)
说明:向数组中追加n个元素,返回第一个元素的地址,步骤与ngx_array_push基本一致

ngx_list_t
源码文件:ngx_list.h|c
定义:
struct ngx_list_part_s {
  void *elts;//数据块首地址
  ngx_unit_t nelts;//元素个数
  ngx_list_part_s *next;//下一个结点
};

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_t 实际上是一个链表,链表的每一个结点都是数组,数组的元素个数是nalloc, 大小是size

常用函数/宏:
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size),
说明:创建一个新的list,并且为首结点分配内存,设置成员变量,并将last也指向首结点
 
void *ngx_list_push(ngx_list_t *l)
说明:向list中插入一个元素。
(1)如果list的last节点已经满了(last->nelts == nalloc),就申请一个新的节点,插入到list的末尾,成为新的last节点,否则跳到第二步
(2)返回last节点的未分配内存块的首地址 
(3)将last节点的nelts加1

ngx_queue_t
源码文件:ngx_queue.h|c
定义:
struct ngx_queue_s {
  ngx_queue_t *prev;//上一个节点
  ngx_queue_t *next;//下一个节点
};

说明: 这是一个带哨兵节点的双向链表
常用函数/宏:
#define Ngx_queue_init(q)
说明:初始化链表,q->prev和q->next都指向q
 
#define Ngx_queue_empty(h)
说明:判断链表是否为空(h == (h)->prev)
 
#define Ngx_queue_insert_head(h, x)
说明:在链表头部插入一个节点
 
#define ngx_queue_insert_tail(h, x)
说明:在链表尾部插入一个节点
 
#define ngx_queue_head(h)
说明:返回第一个节点
 
#define ngx_queue_last(h)
说明: 返回最后一个节点
 
#define ngx_queue_sentinel(h)
说明: 返回哨兵节点
 
#define ngx_queue_next(q)
说明: 返回q节点的下一个结点
 
#define ngx_queue_prev(q)
说明: 返回q节点的上一个节点
 
#define ngx_queue_remove(x)
说明: 从链表中删除x节点
 
#define ngx_queue_split(h, q, n)
说明:分隔链表,将h链表以q为界分割成两个链表,q之前的节点依旧属于h列表,q以及q之后的节点属于n链表(n为新的空节点)
 
#define ngx_queue_add(h, n)
说明:将n链表添加到h链表末尾

ngx_hash_t
源码文件:ngx_hash.h|c
定义:
哈希表元素结构
typedef struct {
  void *value;//数据地址
  u_short len;//数据长度
  u_char name[1];//元素名
} ngx_hash_elt_t;

哈希表结构
typedef struct {
  ngx_hash_elt_t **buckets;//元素数组指针
  ngx_uint_t size;//桶的个数
} ngx_hash_t;

带通配符的key的hash表
typedef struct {
  ngx_hash_t hash;
  void *value;
} ngx_hash_wildcard_t;

哈希key
typedef struct {
  ngx_str_t key;//key名称
  ngx_uint_t key_hash;//key的hash值
  void *value;//key对应的value 
} ngx_hash_key_t;

混合哈希表
typedef struct {
  ngx_hash_t *hash;//不带通配符的key的hash表
  ngx_hash_wildcard_t *wc_head;//前面带通配符的key的hash表
  ngx_hash_wildcard_t *wc_tail;//后面带通配符的key的hash表
} ngx_hash_combined_t;

哈希表初始化结构
typedef struct {
  ngx_hash_t *hash;//如果为NULL,初始化完成后指向新创建的hash表,如果不为NULL,所有数据将插入该字段指向的hash表
  ngx_hash_key_pt key;//生成hashkey的函数
  ngx_uint_t max_size;//哈希表中桶的最大个数
  ngx_uint_t bucket_size;//哈希表桶的最大大小,单位字节
  char *name;//哈希表名
  ngx_pool_t *pool;//分配内存使用的pool
  ngx_pool_t *temp_pool;//临时pool,初始化完成后可以释放和销毁
} ngx_hash_init_t;

用于构造组合hash表的结构体
typedef struct {
  ngx_uint_t hsize;
  ngx_pool_t *pool;
  ngx_pool_t *temp_pool;//临时内存池,用于在创建hash表结构中临时申请的内存,hash表构造完成后可以释放
  ngx_array_t keys;//不带通配符的key 的数组
  ngx_array_t *keys_hash;
  ngx_array_t dns_wc_head;//前部带通配符的key的数组
  ngx_array_t *dns_wc_head_hash;
  ngx_array_t dns_wc_tail;
  ngx_array_t *dns_wc_tail_hash;//后部带通配符的key的数组
} ngx_hash_keys_arrays_t;

typedef struct {
  ngx_uint_t hash;
  ngx_str_t key;
  ngx_str_t value;
  u_char *lowcase_key;
} ngx_table_elt_t;


说明:
常用函数/宏:
ngx_int_t ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
说明:hash表初始化函数.该函数根据hinit结构体的max_size和bucket_size以及names数组元素的内存占用大小,计算出合适的桶数量,并为每个桶分配内存,然后对names数组里的每一个元素的hash_key值进行二次哈希,将元素的值,长度以及小写名保存在对应的桶内。如果hinit的hash为NULL,就将hash指向新创建的哈希表,否则就将所有数据插入hash指向的哈希表中
 
void *ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len)
说明:元素查找函数。该函数对key进行哈希 找到对应的桶,并在桶内查找len成员等于len并且name成员与name参数相同的元素,如果找到 ,返回元素的value,否则返回NULL
 
#define ngx_hash(key, c) ((ngx_uint_t)key * 31 + c)
说明: 基础hash值计算
 
ngx_uint_t ngx_hash_key(u_char *data, size_t len)
说明:nginx的哈希key生成算法。原理是将0作为key初始值,然后对data的每一个字节都进行ngx_hash计算,将结果赋予key,将最后得到的key作为结果返回
 
ngx_uint_t ngx_hash_key_lc(u_char *data, size_t len)
说明:nginx的哈希key生成算法,原理与ngx_hash_key类似,区别在于是用每个字节的小写值进行ngx_hash计算
 
ngx_uint_t ngx_hash_strlow(u_char *dst, u_char *src, size_t)
说明: 该算法是将src的每个字节的小写值赋予dst的对应位置,然后对dst使用ngx_hash计算key,本质上与ngx_hash_key_lc一样,只是 多了一个赋值
 
ngx_int_t ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
说明:初始化ha,主要是根据type进行hash表桶数量的计算以及成员的内存分配
 
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,自动根据是否带有通配符以及通配符的位置将key保存到ha对应的成员中(keys, dns_wc_tail或者dns_wc_head)
 
ngx_int_t ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
说明:初始化带通配符的key的hash表。不能同时用于前部带通配符和后部带通配符的key

ngx_rbtree_t
源码文件:ngx_rbtree.h|c
定义:
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;//数据,没什么用
};

struct ngx_rbtree_s {
    ngx_rbtree_node_t     *root;//红黑树根节点
    ngx_rbtree_node_t     *sentinel;//哨兵节点
    ngx_rbtree_insert_pt   insert;//插入结点函数
};

typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);


说明:
nginx的红黑树是基于算法导论里描述的红黑树实现的,在定时器的管理中使用。

常用函数/宏:
ngx_rbtree_init(tree, s, i)
说明:初始化红黑树,s是哨兵节点,i是插入结点函数

void ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node)
说明:向红黑树中插入结点

void ngx_rbtree_delete(ngx_rbtree_t *tree, ngx_rbtree_node_t *node)
说明:删除红黑树中node表示的节点



ngx_radix_tree_t
源码文件:
定义:
说明:
常用函数/宏:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值