设为首页 加入收藏

TOP

Nginx源码分析:ngx_list_t单链表
2014-04-07 00:39:44 来源: 作者: 【 】 浏览:278
Tags:Nginx 源码 分析 ngx_list_t 单链表

  目录

  1、ngx_list_t的定义

  2、操作ngx_list_t的方法

  1、ngx_list_t的定义

  ngx_list_t是一个链表容器,链表中的每个元素都是一个数组,ngx_list_t描述整个链表,ngx_list_part_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; // 指向下一个链表元素ngx_list_part_t的地址

  };

  typedef struct {

  ngx_list_part_t *last; // 链表的最后一个数组元素

  ngx_list_part_t part; // 链表的第一个数组元素

  size_t size; //数组中每一个元素占有的空间大小

  ngx_uint_t nalloc; // 每个ngx_list_part_t数组最多可存储的元素个数

  ngx_pool_t *pool; // 链表中管理内存分配的内存池对象

  } ngx_list_t;

  ngx_list_t内存图:

  2、操作ngx_list_t的方法

  /*

  函数名:ngx_list_create

  参数:pool是内存池,n是给每个数组预分配的元素个数,size是数组中的每个元素的的大小。

  功能:创建一个链表,并分配n个大小为size的元素作为链表的第一个数组成员。

  */

  ngx_list_t *

  ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)

  {

  ngx_list_t *list;

  // 分配ngx_list_t结构体大小的内存

  list = ngx_palloc(pool, sizeof(ngx_list_t));

  if (list == NULL) {

  return NULL;

  }

 

  // 预分配n个size大小的内存,作为链表数组成员中的元素, list->part.elt指向该地址

  list->part.elts = ngx_palloc(pool, n * size);

  if (list->part.elts == NULL) {

  return NULL;

  }

  list->part.nelts = 0;

  list->part.next = NULL;

  list->last = &list->part;

  list->size = size;

  list->nalloc = n;

  list->pool = pool;

  return list;

  }

  /*

  函数名:ngx_list_init

  参数:list为链表名,pool是内存池,n是给每个数组预分配的元素个数,size是数组中的每个元素的的大小。

  功能:分配n个大小为size的元素作为链表的第一个数组成员。

  */

  static ngx_inline ngx_int_t

  ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)

  {

  // 预分配n个size大小的内存,作为链表数组成员中的元素, list->part.elt指向该地址

  list->part.elts = ngx_palloc(pool, n * size);

  if (list->part.elts == NULL) {

  return NGX_ERROR;

  }

  list->part.nelts = 0;

  list->part.next = NULL;

  list->last = &list->part;

  list->size = size;

  list->nalloc = n;

  list->pool = pool;

  return NGX_OK;

  }

  /*

  函数名:ngx_list_push

  参数:l为链表名

  功能:向链表中添加新元素,返回新增元素的首地址

  */

  void *

  ngx_list_push(ngx_list_t *l)

  {

  void *elt;

  ngx_list_part_t *last;

  last = l->last;

  // 若当前最后一个数组中元素已存满,则分配一个新的数组

  if (last->nelts == l->nalloc) {

  /* the last part is full, allocate a new list part */

  // 分配一个新的链表元素ngx_list_part_t

  last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));

  if (last == NULL) {

  return NULL;

  }

  // last->elts指向新分配的数组

  last->elts = ngx_palloc(l->pool, l->nalloc * l->size);

  if (last->elts == NULL) {

  return NULL;

  }

  last->nelts = 0;

  last->next = NULL;

  // 链表中最后一个元素为新分配的链表元素ngx_list_part_t

  l->last->next = last;

  l->last = last;

  }

  // 指向数组中新增元素的地址

  elt = (char *) last->elts + l->size * last->nelts;

  last->nelts++;

  // 返回新增元素的首地址

  return elt;

  }

 

  // 预分配n个size大小的内存,作为链表数组成员中的元素, list->part.elt指向该地址

  list->part.elts = ngx_palloc(pool, n * size);

  if (list->part.elts == NULL) {

  return NULL;

  }

  list->part.nelts = 0;

  list->part.next = NULL;

  list->last = &list->part;

  list->size = size;

  list->nalloc = n;

  list->pool = pool;

  return list;

  }

  /*

  函数名:ngx_list_init

  参数:list为链表名,pool是内存池,n是给每个数组预分配的元素个数,size是数组中的每个元素的的大小。

  功能:分配n个大小为size的元素作为链表的第一个数组成员。

  */

  static ngx_inline ngx_int_t

  ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)

  {

  // 预分配n个size大小的内存,作为链表数组成员中的元素, list->part.elt指向该地址

  list->part.elts = ngx_palloc(pool, n * size);

  if (list->part.elts == NULL) {

  return NGX_ERROR;

  }

  list->part.nelts = 0;

  list->part.next = NULL;

  list->last = &list->part;

  list->size = size;

  list->nalloc = n;

  list->pool = pool;

  return NGX_OK;

  }

  /*

  函数名:ngx_list_push

  参数:l为链表名

  功能:向链表中添加新元素,返回新增元素的首地址

  */

  void *

  ngx_list_push(ngx_list_t *l)

  {

  void *elt;

  ngx_list_part_t *last;

  last = l->last;

  // 若当前最后一个数组中元素已存满,则分配一个新的数组

  if (last->nelts == l->nalloc) {

  /* the last part is full, allocate a new list part */

  // 分配一个新的链表元素ngx_list_part_t

  last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));

  if (last == NULL) {

  return NULL;

  }

  // last->elts指向新分配的数组

  last->elts = ngx_palloc(l->pool, l->nalloc * l->size);

  if (last->elts == NULL) {

  return NULL;

  }

  last->nelts = 0;

  last->next = NULL;

  // 链表中最后一个元素为新分配的链表元素ngx_list_part_t

  l->last->next = last;

  l->last = last;

  }

  // 指向数组中新增元素的地址

  elt = (char *) last->elts + l->size * last->nelts;

  last->nelts++;

  // 返回新增元素的首地址

  return elt;

  }

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇windows下C++ socket服务器 下一篇Solaris搭建64位C语言开发环境

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)
·Redis配置中`require (2025-12-26 03:18:58)
·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)