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都会动态的查找( ...
随机推荐
- FlyMcu下载时的问题
引用:http://www.openedv.com/forum.php?mod=viewthread&tid=69398&page=1#pid396135 和楼下李智鹏用普中科技的ST ...
- java获得磁盘、网络实时I/O速率
最近项目中需要一个平台硬件资源的监控模块,当时采用了Sigar中api,但是做到针对磁盘和网络的实时I/O速率的时候发现Sigar并没有直接支持的接口.于是……它就诞生了.底层采用C++编写,通过ja ...
- 2018-10-8-Win10-使用-GHO-安装出现-UWP-软件打开闪退-应用商店无法安装软件
title author date CreateTime categories Win10 使用 GHO 安装出现 UWP 软件打开闪退 应用商店无法安装软件 lindexi 2018-10-8 18 ...
- 8_InlineHook
1 shellcode低2Gb警告.应使用高2GB 稳定 : 在内核挂钩子: 由于每个进程的低2gb 的数据是不同的:所以 在内核挂钩子 因该把 代码 放在 高 2gb. 方法1(申请): 比如 使用 ...
- C++调用python(C++)
C++源代码:python部分就是正常的python代码 #include <string.h> #include <math.h> #include "iostre ...
- LUOGU P4394 [BOI2008]Elect 选举 (背包)
传送门 解题思路 一眼看上去就像个背包,然后就是\(0/1\)背包改一改,结果发现过不了样例.后来想了一下发现要按\(a\)从大到小排序,因为如果对于一个>=总和的一半但不满足的情况来说,把最小 ...
- 应用程序正常初始化(0xc0150002)失败的终极解决方案
转自VC错误:http://www.vcerror.com/?p=62 最近做一个项目写了一个VC6下的MFC程序,结果传到别人的机子上(WIN7)出现了应用程序正常初始化(0xc0150002)失败 ...
- 1 A+B问题
原题网址: http://www.lintcode.com/zh-cn/problem/a-b-problem/# 给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符. 注意事项 你不需 ...
- java中字符数组与字符串之间互相转换的方法
public static void main(String[] args) { //1.字符数组 转换成 字符串 //(1)直接在构造String时转换 char[] array = new cha ...
- python安装requests第三方模块
2018-08-28 22:04:51 1 .下载到桌面后解压,放到python的目录下 ------------------------------------------------------- ...