nginx源码分析--数组链表
来源:互联网 发布:珠海知想科技官网 编辑:程序博客网 时间:2024/05/18 02:13
数组和链表的优缺点我们都知道,nginx的数组链表结合了这两种数据结构的优点,表面是链表,链表里每个节点是一个固定大小的数组。结构如下图。
ngx_list.h
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#ifndef _NGX_LIST_H_INCLUDED_#define _NGX_LIST_H_INCLUDED_#include <ngx_config.h>#include <ngx_core.h>typedef struct ngx_list_part_s ngx_list_part_t;/* ngx_list是一个数组链表,表面是一个链表,然后链表里的每一个节点都是一个固定大小的数组, ngx_list_t是整个结构的领导者,他指向ngx_list_part_s,ngx_list_part_s指向数组的存储空间, 因为链表中每个节点,对应的数组可以存储多少个元素,每个元素的大小是固定的,所以这些元数据是存在ngx_list_s中, 没必要每个节点都存一份。ngx_list_part_s就是这个链表中的节点结构体,*/struct ngx_list_part_s { void *elts; // 数组首地址 ngx_uint_t nelts; // 数组已经存储了多少个元素 ngx_list_part_t *next; // 指向下一个节点的指针};typedef struct { /* 最后一个数组节点的结构体指针,这个指针指向的节点是当前也是唯一一个可以用来存储数据的节点, 每次需要存储数据的时候,都是从last指针指向的节点开始找的,如果存满了就继续增加节点,此时last指向新的 节点,last一直指向当前可以存储数据的数据节点。 */ ngx_list_part_t *last; ngx_list_part_t part; // 第一个数组节点的结构体 size_t size; // 数组中,每个元素的大小 ngx_uint_t nalloc; // 每个数组节点可以存储多少个元素 ngx_pool_t *pool; // 用来分配内存的pool} ngx_list_t;ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);/* 初始化数组链表函数 @param list需要初始化的链表结构体 @param pool 用于分配内存的pool @param n 该数组分配共可以存储几个元素 @param size 该数组中每个元素的大小 @return NGX_OK | NGX_ERROR*/static ngx_inline ngx_int_t ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size){ // 分配一个n*size大小的数组。并用赋值给第一个链表节点的list->part.elts,指向数组的首地址 list->part.elts = ngx_palloc(pool, n * size); if (list->part.elts == NULL) { return NGX_ERROR; } // 数组已存0个元素 list->part.nelts = 0; // 下一个链表节点 list->part.next = NULL; // 此时,第一个节点是最后一个节点,需要取地址 list->last = &list->part; // 每个链表节点中,每个数组元素的大小 list->size = size; // 每个链表节点中,数组最多可以存储多少个元素 list->nalloc = n; list->pool = pool; return NGX_OK;}/* * * the iteration through the list: * * part = &list.part; * data = part->elts; * * for (i = 0 ;; i++) { * * if (i >= part->nelts) { * if (part->next == NULL) { * break; * } * * part = part->next; * data = part->elts; * i = 0; * } * * ... data[i] ... * * } */void *ngx_list_push(ngx_list_t *list);#endif /* _NGX_LIST_H_INCLUDED_ */
ngx_list.c
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#include <ngx_config.h>#include <ngx_core.h>/* 创建数组链表函数 @param pool 用于分配内存的pool @param n 该数组分配共可以存储几个元素 @param size 该数组中每个元素的大小 @return 指向数组链表的结构体指针 ngx_list_t*/ngx_list_t * ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size){ ngx_list_t *list; // 分配一个ngx_list_t结构体大小的空间,用来存储数组链表的一些信息 list = ngx_palloc(pool, sizeof(ngx_list_t)); if (list == NULL) { return NULL; } // 分配n * size大小的数组,并初始化第一个数组节点,使得第一个数组节点的指针指向分配的内存 list->part.elts = ngx_palloc(pool, n * size); if (list->part.elts == NULL) { return NULL; } // 同ngx_list_init函数 list->part.nelts = 0; list->part.next = NULL; list->last = &list->part; list->size = size; list->nalloc = n; list->pool = pool; return list;}/* 返回可以用来存储数据的首地址,如果第一个数组节点没有空间就往后面的节点找,如果都没有空间就动态增加数组节点 @param l 存储数据的链表 @return 可以用来存储数据的首地址*/void * ngx_list_push(ngx_list_t *l){ void *elt; ngx_list_part_t *last; last = l->last; // 最后一个数组节点都已经存满了,需要增加新的数组节点 if (last->nelts == l->nalloc) { /* the last part is full, allocate a new list part */ // 先开辟一个新的数组节点结构体,用来存储数组节点的相关信息 last = ngx_palloc(l->pool, sizeof(ngx_list_part_t)); if (last == NULL) { return NULL; } // 开辟一块存储数据的内存,并交给last管理 last->elts = ngx_palloc(l->pool, l->nalloc * l->size); if (last->elts == NULL) { return NULL; } // 新开辟的数组存储了0个元素 last->nelts = 0; // 该数组节点是最后一个数组节点,next为NULL last->next = NULL; // 把新开辟的数组节点插入到链表的最后面 l->last->next = last; // 此时新开辟的数组节点是最后一个节点,也是唯一一个可用节点,可用的意思是还可以用来存储元素 l->last = last; } // 不管需不需要新增数组节点,last->elts + l->size * last->nelts此时都指向第一个可用的地址 elt = (char *) last->elts + l->size * last->nelts; // 存储的元素个数加1 last->nelts++; // 返回可存储数据的首地址,nginx里都是返回一个地址,然后在push函数外进行数据存储,而不是在push函数里操作 return elt;}
0 0
- nginx源码分析--数组链表
- Nginx源码分析-数组
- 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
- Nginx源码分析---链表结构ngx_list_t
- 文章2:Nginx源码分析-ngx_array_t动态数组
- Nginx高级数据结构源码分析(二)-----动态数组
- Nginx源码分析 - 基础数据结构篇 - 数组结构 ngx_array.c
- nginx源码分析—链表结构ngx_list_t
- 第七届 蓝桥杯 决赛 碱基(哈希,不保证对)
- mysql取周,月,年数据
- U盘挂载
- ng-if的使用
- IO与文件读写---同步/异步与阻塞/非阻塞的区别(转) _适用于TI dsp驱动
- nginx源码分析--数组链表
- 客户端底层 Socket 实现IPV4 IPV6网络环境的兼容
- errno的一些错误定义
- 线程池的原理及实现
- jQuery的属性过滤选择器
- weka文本聚类(1)--概述
- 稀疏矩阵的压缩存储
- Win10系统下WampServer不能正常运行原因深度探索
- Java之设计模式(工厂模式)