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都会动态的查找( ...
随机推荐
- 用PS制作APP的界面图片
今天就教大家怎么做出这种厚度的地方还不是白色的,而是根据界面内容交相呼应的图案的APP界面展示图片. 以苹果5S的尺寸为例. 步骤: 1.新建一个画布尺寸为:640*1136,然后保存,命名如:5S效 ...
- java 多项式
/****************************************************************************** * Compilation: javac ...
- AM8后台历史数据手工清理方法
AM8后台历史数据手工清理方法 数据清理目前通过bat脚本将windows任务计划来完成 Bat 路径位置: \ActiveSoft\Am8Svr\STKServer\Data (请根据服务安装 ...
- mysql主从同步的键值冲突问题的解决方法
转自https://njs375666635.iteye.com/blog/2242067 多主互备和主从复制有一些区别,因为多主中都可以对服务器有写权限,所以设计到自增长重复问题 出现的问题(多主自 ...
- 【JZOJ6367】工厂(factory)
description 大神 wyp 开了家工厂,工厂有 n 个工人和 p 条流水线. 工厂的工人都是睡神,因此第 i 个工人只会在 si 至 ti 时刻才会工作. 每个工人都会被分派到一条流水线上, ...
- GCRoots 对象
GC Roots 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中的类静态属性引用的对象 方法区中的常量引用的对象 原生方法栈(Native Method Stack)中 JNI 中引用的对象 可 ...
- 【未完成】Jmeter接口自动化测试:参数化设置
1. 从CSV文件读取参数 创建一个CVS文件,文件第一行不写参数名,直接从参数值开始,每一列代表一个参数 在测试计划或者线程组中,添加一个配置元件-->CSV 数据文件设置 Filename: ...
- 使用ProGuard混淆JAR包
1.在Input/OutPut选项下面,add input 导入需要混淆的jar包2.点击add output,设置混淆后输出jar包的名字和路径.如下图:3.在下面的编辑区右边点击add增加要混淆的 ...
- 阿里P8架构师谈:数据库分库分表、读写分离的原理实现,使用场景
本文转载自:阿里P8架构师谈:数据库分库分表.读写分离的原理实现,使用场景 为什么要分库分表和读写分离? 类似淘宝网这样的网站,海量数据的存储和访问成为了系统设计的瓶颈问题,日益增长的业务数据,无疑对 ...
- VS2010-MFC(常用控件:编辑框Edit Control)
转自:http://www.jizhuomi.com/software/181.html 编辑框(Edit Control)是一种很常用的控件,我们可以在编辑框中输入并编辑文本.在前面加法计算器的例子 ...