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都会动态的查找( ...
随机推荐
- 2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)
2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred) easy: ACE ...
- 21个CSS技巧
级联样式表(CSS)在当代Web设计中已经成为重要的环节,如果没有CSS现在的网站将像10年前一样不堪入目.随着CSS技术的普及,越来越多的高质量CSS教程涌入互联网,让我们的学习更加方便. 1.CS ...
- Docker学习のDocker的简单应用
一.常见基本docker命令 docker是在一个linux虚拟机上运行的(对于windows来说),打开Docker quickStart terminal,就连街上了docker的 daemon ...
- 机器突然宕机导致hdfs启动一直超时的行为
今天手里其中一个集群几个机器突然宕机,启动hdfs一直超时. clouder-scm-agent主要报了这个错RROR: Unexpected error 'getpwuid(): uid not f ...
- Spark Streaming的简单介绍
本文讲解Spark流数据处理之Spark Streaming.本文的写作时值Spark 1.6.2发布之际,Spark 2.0预览版也已发布,Spark发展如此迅速,请随时关注Spark Stream ...
- 2019-8-24-win10-本地适配器不支持重要的低能耗控制器状态
title author date CreateTime categories win10 本地适配器不支持重要的低能耗控制器状态 lindexi 2019-8-24 16:2:33 +0800 20 ...
- C++之constexpr
一.常量表达式:是指值不会改变并且在编译过程就能得到计算结果的表达式.一个对象是不是常量表达式是由它的数据类型和初始值共同决定. ;//虽然初始值是字面值常量,但是它的数据类型只是普通int. con ...
- The linux command 之定制提示符
一.提示符分解 默认提示符如下所示: [me@linuxbox ~]$ 可以看出它包括我们的用户名.主机名.当前工作目录.提示符是由PS1变量定义的. [me@linuxbox ~]$ echo $P ...
- php+jquery 上拉加载
<script type="text/javascript"> var resflow = true,pages =2; var ps=$("#ids&quo ...
- 0916CSP-S模拟测试赛后总结
40分-rank35. 不想找借口.实力不行. 赛时状态没出什么大问题.就是实力太弱了. 天皇又AK了.去问了一下,他说全是简单题…… 后来发现一些人用非正解AC了. 但是天皇题题正解题题首切啊. 还 ...