nginx 源码:动态数组
来源:互联网 发布:rt809编程器使用方法 编辑:程序博客网 时间:2024/05/02 16:46
动态数组
这玩意吧,应该最简单的一个。
动态数组有以下特征:
- 访问速度快。
- 允许元素的个数具体不确定性。也就说是可以动态扩充数组
在ngnix中,动态数组的内存是通过向ngnix的内存池内申请的,所以动态扩充数组的时候特别方便,由ngnix统一管理。
动态数组的结构和方法
动态数组的结构
struct ngx_array_s { void *elts; //指向首地址 ngx_uint_t nelts;//数组中已经使用了的个数 size_t size;//每个元素占用内存的大小 ngx_uint_t nalloc;//当前数组中能内容多少个元素个数 ngx_pool_t *pool;//用于分配内存池};
支持的方法和实现
这是头文件部分的内容,ngx_array.c里面会有具体函数的实现
/*创建一个动态数组,只用传入需要每个元素的大小和需要多少个元素,会返回一个指向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_int_tngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size){ /* * set "array->nelts" before "array->elts", otherwise MSVC thinks * that "array->nelts" may be used without having been initialized */ array->nelts = 0; array->size = size; array->nalloc = n; array->pool = pool; array->elts = ngx_palloc(pool, n * size); if (array->elts == NULL) { return NGX_ERROR; } return NGX_OK;}
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#include "mytest_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; } a->elts = ngx_palloc(p, n * size); if (a->elts == NULL) { return NULL; } a->nelts = 0; a->size = size; a->nalloc = n; a->pool = p; return a;}voidngx_array_destroy(ngx_array_t *a){ ngx_pool_t *p; p = a->pool; /*从下面的代码来看,删除内存就是改改d.last的位置就好了*/ 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) { /* * the array allocation is the last in the pool * and there is space for new allocation * * zy:这样的情况下只增加了一个元素 */ p->d.last += a->size;//这里只增加了一个元素的位置 a->nalloc++;//相应能够容纳的个数也会增加 } else { /* allocate a new array * zy:此种情况下翻倍 * */ new = ngx_palloc(p, 2 * size); if (new == NULL) { return NULL; } ngx_memcpy(new, a->elts, size); a->elts = new; a->nalloc *= 2; } } //新添加的元素的指针首地址 elt = (u_char *) a->elts + a->size * a->nelts; a->nelts++; return elt;}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) { /* * the array allocation is the last in the pool * and there is space for new allocation * zy:这样的情况下只是需要多少新内存,就给的多少内存 */ p->d.last += size; a->nalloc += n; } else { /* allocate a new array * 翻倍内存 * */ nalloc = 2 * ((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 = (u_char *) a->elts + a->size * a->nelts; a->nelts += n; return elt;}
运行的小例子
为了运行小例子,还需要调用有关内存池的一些方法,这里就没贴涉及内存的源码了,所以说也许在拷贝这几个文档也不能用,只能参考一下。
main
#include "mytest_ngx_core.h"typedef struct { u_char *data; int num;}TestNode;int main() {ngx_pool_t *pool=ngx_create_pool(16384);ngx_array_t *dynamicArray=ngx_array_create(pool,1,sizeof(TestNode));/*注意添加元素的方式*/TestNode* a=ngx_array_push(dynamicArray);a->num=1;a=ngx_array_push(dynamicArray);a->num=2;TestNode* b=ngx_array_push_n(dynamicArray,3);b->num=3;(b+1)->num=4;(b+2)->num=5;TestNode *nodeArray=dynamicArray->elts;ngx_uint_t arraySeq=0;for(;arraySeq<dynamicArray->nelts;arraySeq++){a=nodeArray+arraySeq;printf("%d\n",a->num);}}
ngx_array.h
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#include "mytest_ngx_core.h"//为了能够运行例子,我自己写的,包括hash表和动态数组#ifndef _NGX_ARRAY_H_INCLUDED_#define _NGX_ARRAY_H_INCLUDED_struct ngx_array_s { void *elts; //指向首地址 ngx_uint_t nelts;//数组中已经使用了的个数 size_t size;//每个元素占用内存的大小 ngx_uint_t nalloc;//当前数组中能内容多少个元素个数 ngx_pool_t *pool;//用于分配内存池};/*创建一个动态数组,只用传入需要每个元素的大小和需要多少个元素*/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_int_tngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size){ /* * set "array->nelts" before "array->elts", otherwise MSVC thinks * that "array->nelts" may be used without having been initialized */ array->nelts = 0; array->size = size; array->nalloc = n; array->pool = pool; 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 "mytest_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; } a->elts = ngx_palloc(p, n * size); if (a->elts == NULL) { return NULL; } a->nelts = 0; a->size = size; a->nalloc = n; a->pool = p; return a;}voidngx_array_destroy(ngx_array_t *a){ ngx_pool_t *p; p = a->pool; /*从下面的代码来看,删除内存就是改改d.last的位置就好了*/ 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) { /* * the array allocation is the last in the pool * and there is space for new allocation * * zy:这样的情况下只增加了一个元素 */ p->d.last += a->size;//这里只增加了一个元素的位置 a->nalloc++;//相应能够容纳的个数也会增加 } else { /* allocate a new array * zy:此种情况下翻倍 * */ new = ngx_palloc(p, 2 * size); if (new == NULL) { return NULL; } ngx_memcpy(new, a->elts, size); a->elts = new; a->nalloc *= 2; } } //新添加的元素的指针首地址 elt = (u_char *) a->elts + a->size * a->nelts; a->nelts++; return elt;}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) { /* * the array allocation is the last in the pool * and there is space for new allocation * zy:这样的情况下只是需要多少新内存,就给的多少内存 */ p->d.last += size; a->nalloc += n; } else { /* allocate a new array * 翻倍内存 * */ nalloc = 2 * ((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 = (u_char *) a->elts + a->size * a->nelts; a->nelts += n; return elt;}
mytest_ngx_core.h
/* * mytest_ngx_core.h *这我写的类似于ngx_core.h *这个ngx_core.h里面包含了很都头文件,给很多变量取了别名 *这样别的文件只用包含这个头文件就好了 * Created on: Apr 1, 2014 * Author: zy */#ifndef MYTEST_NGX_CORE_H_#define MYTEST_NGX_CORE_H_/*宏使得到的内存地址为NGX_ALIGNMENT的倍数。数据对齐,可以避免cpu取值时,要进行两次IO */#define ngx_align_ptr(p, a) \ (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))#ifndef NGX_ALIGNMENT#define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */#endif#define NGX_OK 0#define NGX_ERROR -1#define NGX_AGAIN -2#define NGX_BUSY -3#define NGX_DONE -4#define NGX_DECLINED -5#define NGX_ABORT -6#define ngx_cacheline_size 32//内存中对齐的要求,能够更快的找到对应的位置,我是32位的机子,所以我设置为这个值。//但不是书写的,是我参考了很多网页猜出来的typedef unsigned short u_short;typedef unsigned int ngx_uint_t;typedef unsigned char u_char;typedef long int ngx_int_t;typedef struct ngx_pool_s ngx_pool_t;typedef struct ngx_array_s ngx_array_t;typedef unsigned long int uintptr_t;#define ngx_memzero(buf, n) (void) memset(buf, 0, n)#define ngx_strlen(s) strlen((const char *) s)#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)#define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1))#define ngx_tolower(c) (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)#define ngx_strncmp(s1, s2, n) strncmp((const char *) s1, (const char *) s2, n)#include <stdlib.h>#include <stddef.h>voidngx_strlow(u_char *dst, u_char *src, size_t n){ while (n) { *dst = ngx_tolower(*src); dst++; src++; n--; }}u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n){ if (n == 0) { return dst; } while (--n) { *dst = *src; if (*dst == '\0') { return dst; } dst++; src++; } *dst = '\0'; return dst;}#include "ngx_palloc.h"#include "ngx_array.h"#include "ngx_hash.h"#include "ngx_alloc.h"#include "ngx_palloc.c"#include "ngx_array.c"#include "ngx_hash.c"#include "ngx_alloc.c"#endif /* MYTEST_NGX_CORE_H_ */
运行结果
asd@asd-desktop:~/workspace/test/src$ ./a.out 12345asd@asd-desktop:~/workspace/test/src$
0 0
- nginx 源码:动态数组
- 文章2:Nginx源码分析-ngx_array_t动态数组
- Nginx高级数据结构源码分析(二)-----动态数组
- Nginx源码分析-数组
- nginx源码分析--数组
- nginx动态数组ngx_array_t
- nginx之动态数组
- 动态数组源码
- Nginx源码分析-connections数组
- Nginx源码分析-connections数组
- Nginx源码分析-connections数组
- nginx的动态数组--ngx_array_t
- 菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t
- 菜鸟nginx源码剖析数据结构篇(一) 动态数组ngx_array_t
- 菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t
- nginx源码分析—数组结构ngx_array_t
- Nginx源码分析---数组结构ngx_array_t
- nginx源码分析—数组结构ngx_array_t
- Android 拦截外拨电话
- 多表关联模型
- 黑马程序员_Java_异常
- spring学习前奏004
- HDU 3065 病毒侵袭持续中
- nginx 源码:动态数组
- Visual Studio 2008 安装失败(“Web 创作组件”无法安装)
- 作业错误修正
- OSGi 探秘系列 (1) - 概述什么是OSGi框架
- JAVA super关键字
- word不支持汉字输入--解决方案
- TCP/IP详解--拥塞控制机制 && RTT时间计算相关的算法
- 一步步学习微软InfoPath2010和SP2010--第十一章节--创建批准流程(7)--approval节
- C++指针参数 动态内存分配和释放