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源码分析——数组的更多相关文章

  1. Nginx源码分析--数组(转)

    原文地址:http://blog.csdn.net/marcky/article/details/5747431 备注:以下关于Nginx源码的分析基于淘宝开源项目Tengine. Nginx中对数组 ...

  2. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  3. Nginx源码分析:3张图看懂启动及进程工作原理

    编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」.   导读:很多工程师及架构师都希望了解及掌握高性能服务器 ...

  4. nginx源码分析线程池详解

    nginx源码分析线程池详解 一.前言     nginx是采用多进程模型,master和worker之间主要通过pipe管道的方式进行通信,多进程的优势就在于各个进程互不影响.但是经常会有人问道,n ...

  5. nginx源码分析--使用GDB调试(strace、 pstack )

    nginx源码分析--使用GDB调试(strace.  pstack ) http://blog.csdn.net/scdxmoe/article/details/49070577

  6. nginx源码分析-源码结构

    本文主要简单介绍nginx源码目录结构.程序编译流程.如何构建学习nginx的环境等.本文以及后续nginx源码分析文章是基于nginx当前(2009-02-27)的稳定版本0.6.35进行的分析,该 ...

  7. nginx源码分析——configure脚本

    源码:nginx 1.13.0-release   一.前言      在分析源码时,经常可以看到类似 #if (NGX_PCRE) .... #endif 这样的代码段,这样的设计可以在不改动源码的 ...

  8. nginx源码分析之hash的实现

    nginx实现了自己的hash数据结构,正如数据结构中讲述的那样,nginx用开放链表法解决冲突,不过不同的是一旦一个hash表被初始化后就不会被修改,即插入和删除,只进行查询操作,所以nginx通过 ...

  9. [nginx] nginx源码分析--SNI性能分析

    概念 我们已经知道什么是SNI,以及如何为用户配置SNI. [nginx] nginx使用SNI功能的方法 问题 通过观察配置文件,可以发现,针对每一个SSL/TLS链接, nginx都会动态的查找( ...

随机推荐

  1. 「LibreOJ NOI Round #2」签到游戏

    题目 瞎猜一下我们只要\(n\)次询问就能确定出\(\{A_i\}\)来 感受一下大概是询问的区间越长代价就越小,比如询问\([l,n]\)或\([1,r]\)的代价肯定不会超过\([l,r]\) 所 ...

  2. 2018湘潭大学程序设计竞赛【D】

    题目链接:https://www.nowcoder.com/acm/contest/105/D 题意:就是数的fib表示方法.按权展开,又按二进制算出结果输出. 题解:贪心和数论吧.找到跟数最接近的f ...

  3. DIV+CSS网页布局常用的一些基础知识

    CSS命名规范 一.文件命名规范 全局样式:global.css:框架布局:layout.css:字体样式:font.css:链接样式:link.css:打印样式:print.css: 二.常用类/I ...

  4. Visual Studio 2010 启动调试报错 “访问OLE注册表的错误”

    错误:访问OLE注册表的错误(异常来自HRESULT:0x8002801C(TYPE_E_REGISTRYACCESS)) 很简单,其实只要 “以管理员身份运行” Visual Studio即可.

  5. Aop 简单实例

    一 , 定义aop @Aspect @Component public class MyAspect { //* com 这里有个 空格 ! @Pointcut("execution(* c ...

  6. Java 局部变量

    Java 局部变量 局部变量声明在方法.构造方法或者语句块中: 局部变量在方法.构造方法.或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁: 访问修饰符不能用于局部变量: 局部变量只在声明 ...

  7. Chrome DNS_PROBE_FINISHED_NXDOMAIN

    win10 下的Chrome访问网站时,提示DNS_PROBE_FINISHED_NXDOMAIN 解决方法很简单: 用管理员身份打开cmd后,运行如下指令即可解决问题. 运行命令: netsh wi ...

  8. Linux g++

    Usage: g++ [options] file...Options:  -pass-exit-codes         Exit with highest error code from a p ...

  9. MAMP mysql无法启动 总结(以后有发现再添加)

    1.错误信息Can't start server : Bind on unix socket: Address already in use 解析:主要原因是上次关闭Mysql是出现异常而导致的, 解 ...

  10. iOS开发之SceneKit框架--SCNGeometry.h

    1.SCNGeometry简介 SCNGeometry负责呈现三维模型的类,它管理者物体的形状.纹理等.它可以由SCNGeometrySource和SCNGeometryElement来构造, 一个S ...