nginx源码分析——数组
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> typedef struct {
// elts指针,指向内存块
void *elts;
// nelts,当前元素数量
ngx_uint_t nelts;
// size,元素大小
size_t size;
// nalloc,当前容量
ngx_uint_t nalloc;
// pool指针,指向内存池
ngx_pool_t *pool;
} ngx_array_t; // 创建数组(内存池,初始容量,元素大小)
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); // 添加n个元素(目标数组,元素数量)
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n); // 初始化数组(目标数组,内存池,初始容量,元素大小)
static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
// nelts,当前元素数量
array->nelts = ;
// size,元素大小
array->size = size;
// nalloc,当前容量
array->nalloc = n;
// pool指针,指向内存池
array->pool = pool;
// elts指针,指向内存块
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> // 创建数组(内存池,初始容量,元素大小)
ngx_array_t *
ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
{
ngx_array_t *a; // 创建数组
a = ngx_palloc(p, sizeof(ngx_array_t));
if (a == NULL) {
return NULL;
} // 初始化数组(目标数组,内存池,初始容量,元素大小)
if (ngx_array_init(a, p, n, size) != NGX_OK) {
return NULL;
} return a;
} // 销毁数组(目标数组)
void
ngx_array_destroy(ngx_array_t *a)
{
ngx_pool_t *p; // pool指针,指向内存池
p = a->pool; // 判断数组元素是否位于内存块的最后位置,如果是直接调整内存块的参数进行删除
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;
} // 如果不是,则由内存池自行回收
} // 添加元素(目标数组)
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; // 判断数组是否位于内存块最后位置,且内存池还有足够的内存空间
if ((u_char *) a->elts + size == p->d.last
&& p->d.last + a->size <= p->d.end)
{
// 如果是,则调整内存池参数,增加数组元素的内存空间
p->d.last += a->size;
a->nalloc++; } else {
// 创建于原数组两倍大的数组元素空间
new = ngx_palloc(p, * size);
if (new == NULL) {
return NULL;
}
ngx_memcpy(new, a->elts, size);
a->elts = new;
a->nalloc *= ;
}
} // elts指针,指向内存块
elt = (u_char *) a->elts + a->size * a->nelts; // 累加元素数量
a->nelts++; // 返回新元素
return elt;
} // 添加n个元素(目标数组,元素数量)
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; // 判断元素数量是否达到最大值
if (a->nelts + n > a->nalloc) { /* the array is full (满了)*/ p = a->pool; // 判断数组是否位于内存块最后位置,且内存池还有足够的内存空间
if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
&& p->d.last + size <= p->d.end)
{
// 调整内存块参数
p->d.last += size;
a->nalloc += n; } else {
// 创建于原数组两倍大的数组元素空间
nalloc = * ((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指针,指向第一个新元素的内存地址
elt = (u_char *) a->elts + a->size * a->nelts; // 累加元素数量
a->nelts += n; // 返回第一个新元素
return elt;
}
nginx源码分析——数组的更多相关文章
- Nginx源码分析--数组(转)
原文地址:http://blog.csdn.net/marcky/article/details/5747431 备注:以下关于Nginx源码的分析基于淘宝开源项目Tengine. Nginx中对数组 ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- Nginx源码分析:3张图看懂启动及进程工作原理
编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」. 导读:很多工程师及架构师都希望了解及掌握高性能服务器 ...
- nginx源码分析线程池详解
nginx源码分析线程池详解 一.前言 nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...
- nginx源码分析--使用GDB调试(strace、 pstack )
nginx源码分析--使用GDB调试(strace. pstack ) http://blog.csdn.net/scdxmoe/article/details/49070577
- nginx源码分析-源码结构
本文主要简单介绍nginx源码目录结构.程序编译流程.如何构建学习nginx的环境等.本文以及后续nginx源码分析文章是基于nginx当前(2009-02-27)的稳定版本0.6.35进行的分析,该 ...
- nginx源码分析——configure脚本
源码:nginx 1.13.0-release 一.前言 在分析源码时,经常可以看到类似 #if (NGX_PCRE) .... #endif 这样的代码段,这样的设计可以在不改动源码的 ...
- nginx源码分析之hash的实现
nginx实现了自己的hash数据结构,正如数据结构中讲述的那样,nginx用开放链表法解决冲突,不过不同的是一旦一个hash表被初始化后就不会被修改,即插入和删除,只进行查询操作,所以nginx通过 ...
- [nginx] nginx源码分析--SNI性能分析
概念 我们已经知道什么是SNI,以及如何为用户配置SNI. [nginx] nginx使用SNI功能的方法 问题 通过观察配置文件,可以发现,针对每一个SSL/TLS链接, nginx都会动态的查找( ...
随机推荐
- 连接mysql并查询
1.将mysql-connector-java-5.1.7-bin.jar放入Jmeter安装目录的bin文件夹中 2.在顶层目录<测试计划>中加载驱动 3.添加JDBC Connecti ...
- linux下创建oracle表空间
来自:http://blog.sina.com.cn/s/blog_62192aed01018aep.html 1 . 登录服务器 2 . 查看磁盘空间是否够大df -h -h更具目前磁盘空间和使用情 ...
- flink流的执行大致流程图
- pytorch clamp 与clamp_区别
pytorch clamp 与clamp_ ,有下划线的表示修改并付给自身,无下划线的表示需要返回处理后的值,比如: h = k.clamp(min=0) #将结果存入h,k保留原值 k.clamp_ ...
- NOIP提高真题整理(2011-2018)-标签
加粗的后面应该会有相应的简单解析(如果没咕的话:)). 2011 day1 T1:铺地毯:逆着铺 T2:选择客栈:按颜色分类枚举+二分答案 T3:Mayan游戏:大模拟dfs+剪枝 day2 T1:计 ...
- HTML加载顺序
一.js执行顺序 //1. 外部引入的js文件,会异步下载并且执行(<script>块中的语句),根据引入的位置会在不同时刻执行 //2.$().ready(function() {}) ...
- Delphi 第一课
Delphi 是面向对象的 可视化的集成开发环境 对象包括属性 方法 事件. 用户事件 对象响应事件 不同的对象响应事件不一样
- Cut the Sequence
Cut the Sequence 有一个长度为n的序列\(\{a_i\}\),现在求将其划分成若干个区间,并保证每个区间的和不超过m的情况下,每个区间的最大值的和的最小值,\(0 < N ≤ 1 ...
- mysql 的特殊函数
1. FORMAT() 函数 函数用于对字段的显示进行格式化 语法: SELECT FORMAT(column_name,format) FROM table_name column_name 必需 ...
- 最大流任务调度——hdu3572二分图建图
很简单的任务调度模板题 把一个工作完成一天的量当做是边 /* 任务调度问题最大流 因为两个任务之间是没有关系的,两天之间也是没有关系的 所以抽象成二分图 任务i在天数[si,ei]之间都连一条双向边, ...