nginx源码分析--数组
来源:互联网 发布:凯立德端口波特率检测 编辑:程序博客网 时间:2024/04/30 19:47
ngx_array.h
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#ifndef _NGX_ARRAY_H_INCLUDED_#define _NGX_ARRAY_H_INCLUDED_#include <ngx_config.h>#include <ngx_core.h>struct ngx_array_s { void *elts; // 指向数组始地址 ngx_uint_t nelts; // 数组里已经存储了几个元素 size_t size; // 数组中每个元素的大小 ngx_uint_t nalloc; // 数组总共可以储存多少个元素 ngx_pool_t *pool; // 数组的内存是由哪个pool分配的};ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);void ngx_array_destroy(ngx_array_t *a);void *ngx_array_push(ngx_array_t *a);void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);/* 数组初始化函数 @param array 储存数组元数据的结构体指针 @param pool 用于分配内存的pool @param n 该数组分配共可以存储几个元素 @param size 该数组中每个元素的大小 @return NGX_OK | NGX_ERROR*/static ngx_inline ngx_int_t ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size){ /* * set "array->nelts" before "array->elts", otherwise MSVC thinks * that "array->nelts" may be used without having been initialized */ // 初始化中数组没有存储元素 array->nelts = 0; // 初始化数组中每个元素的大小 array->size = size; // 数组可以储存n个size大小的元素 array->nalloc = n; array->pool = pool; // 给数组分配n*size大小的内存 array->elts = ngx_palloc(pool, n * size); if (array->elts == NULL) { return NGX_ERROR; } return NGX_OK;}#endif /* _NGX_ARRAY_H_INCLUDED_ */
ngx_array.c
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#include <ngx_config.h>#include <ngx_core.h>/* 创建数组函数 @param pool 用于分配内存的pool @param n 该数组分配共可以存储几个元素 @param size 该数组中每个元素的大小 @return 存储数组元数据的ngx_array_t结构体*/ngx_array_t * ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size){ ngx_array_t *a; // 在pool里给存储元数据的结构体分配内存 a = ngx_palloc(p, sizeof(ngx_array_t)); if (a == NULL) { return NULL; } // 在pool里给数组分配内存,并用a->elts指向始地址 a->elts = ngx_palloc(p, n * size); if (a->elts == NULL) { return NULL; } // 初始化结构体的成员 a->nelts = 0; a->size = size; a->nalloc = n; a->pool = p; return a;}/* 销毁数组函数 这个函数在nginx中并没有用到 @param a 储存数组元数据的结构体指针*/void ngx_array_destroy(ngx_array_t *a){ ngx_pool_t *p; p = a->pool; // 判断是否p->last指针的值是否恰好等于数组的末地址,否则会”释放“数组和p->last之间的数据 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) { p->d.last -= a->size * a->nalloc; } if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) { p->d.last = (u_char *) a; }}/* 在原数组基础增加一个元素空间,如果原数组空间不够需要重新开辟内存 @param a 储存数组元数据的结构体指针 @return elt 新增内存的首地址*/void * ngx_array_push(ngx_array_t *a){ void *elt, *new; size_t size; ngx_pool_t *p; // 数组已存满了 if (a->nelts == a->nalloc) { /* the array is full */ // 数组的总大小 size = a->size * a->nalloc; p = a->pool; // 如果数组的末地址和p->last指针相等并且追加size大小的空间后不会超过p->end,才能追加分配内存 if ((u_char *) a->elts + size == p->d.last && p->d.last + a->size <= p->d.end) { /* * the array allocation is the last in the pool * and there is space for new allocation */ // 在数组末地址处追加size大小的内存,并且nalloc+1表示数组可以数组可以储存的元素个数加1 p->d.last += a->size; a->nalloc++; } // 如果数组满,并且无法追加内存时 else { /* allocate a new array */ // 需要重新开辟大小为原来两倍的内存 new = ngx_palloc(p, 2 * size); if (new == NULL) { return NULL; } // 把原来的数据复制过去 ngx_memcpy(new, a->elts, size); // 数组首地址指针指向新的内存地址 a->elts = new; // 数组容量变为原来的两倍 a->nalloc *= 2; } } /* 数组原来就有空间,或者数组已经存满并且追加内存分配成功,或者数组存满并重新开辟了内存, a->elts + a->size * a->nelts都等于此时数组的第一个可用地址,也就是下一个数据可以由 这个地址开始存储,elt只需要指向此时的数组末地址就行, */ elt = (u_char *) a->elts + a->size * a->nelts; // 数组已存储的元素个数加一 a->nelts++; // 返回数组第一个可用的内存地址,也就是下一个数据可以由这个地址开始存储 return elt;}/* 在原数组基础增加n个元素空间,如果原数组空间不够需要重新开辟内存 @param a 储存数组元数据的结构体指针 @return elt 新增内存的首地址*/void * ngx_array_push_n(ngx_array_t *a, ngx_uint_t n){ void *elt, *new; size_t size; ngx_uint_t nalloc; ngx_pool_t *p; size = n * a->size; // 数组增加n个元素后超过可存储元素的个数 if (a->nelts + n > a->nalloc) { /* the array is full */ p = a->pool; // 同ngx_array_push函数 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last && p->d.last + size <= p->d.end) { /* * the array allocation is the last in the pool * and there is space for new allocation */ p->d.last += size; a->nalloc += n; } else { /* allocate a new array */ /* 如果追加的元素个数n比原来可存储的元素个数a->nalloc还大,否则开辟2*a->nalloc个空间可能还是比n小, 例如之前最大能存储5个,已经存储了2个,现在需要多存储12个,那么5*2<12, ,所以需要重新开辟2*n个空间,保证能多存储n个元素,其他的同ngx_array_push函数。 */ nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc); new = ngx_palloc(p, nalloc * a->size); if (new == NULL) { return NULL; } ngx_memcpy(new, a->elts, a->nelts * a->size); a->elts = new; a->nalloc = nalloc; } } elt = (u_char *) a->elts + a->size * a->nelts; a->nelts += n; return elt;}
0 0
- Nginx源码分析-数组
- nginx源码分析--数组
- Nginx源码分析-connections数组
- Nginx源码分析-connections数组
- Nginx源码分析-connections数组
- nginx源码分析—数组结构ngx_array_t
- Nginx源码分析---数组结构ngx_array_t
- nginx源码分析—数组结构ngx_array_t
- nginx源码分析—数组结构ngx_array_t
- nginx源码分析—数组结构ngx_array_t
- nginx源码分析—数组结构ngx_array_t
- Nginx源码分析—数组结构ngx_array_t
- nginx源码分析--数组链表
- 文章2:Nginx源码分析-ngx_array_t动态数组
- Nginx高级数据结构源码分析(二)-----动态数组
- Nginx源码分析 - 基础数据结构篇 - 数组结构 ngx_array.c
- nginx 源码:动态数组
- nginx源码分析
- apache和nginx那点事儿--阻塞和异步(非常清楚)
- maven引入ojdbc
- 2017.05.11-1新建IDEA项目
- Java 匿名类详解
- 第八届ACM山东省赛 J company
- nginx源码分析--数组
- linux 环境搭建solr5.5.4搜索服务
- Nicescroll滚动条插件的用法
- 多线程的应用场景
- Java文件流
- 给定按升序排序的整数数组,找到给定目标值的起始和终止位置。 您的算法的运行时复杂度必须是O(log n)的顺序。
- Unicode
- Android自定义动画酷炫的提交按钮
- Oracle 临时表空间管理