nginx源码阅读笔记.array和list数据结构
来源:互联网 发布:淘宝vip专享活动 编辑:程序博客网 时间:2024/06/16 23:11
1.概述
nginx中,array和list 的实现 和queue的实现不同,queue的实现是不依赖于具体的结构的,可以申明任何结构体只要该结构体中间含有queue的实例就可以将它们组织起来,那么queue的对象的内存分配需要(用户自己申请),在分配的包含queue的对象时已经分配好,
而list和array 的实现则时初始化一个list或者array, 自定义的结构的内存分配任务交给list和array完成,在向list 和array插入的时候就返回容器向内存申请的内存,用户直接可以在该地址上完成操作.
2.代码
#include <stdlib.h>typedef unsigned int u_int;typedef struct ngx_list_part_s ngx_list_part_t;typedef struct ngx_list_s ngx_list_t;struct ngx_list_part_s{ void *elts; u_int nelts; ngx_list_part_t *next;};struct ngx_list_s{ ngx_list_part_t *last; ngx_list_part_t part; u_int ele_size; //element size u_int nalloc; //element count each page;};static inline int ngx_list_init(ngx_list_t* list,u_int sz,u_int n){ list->part.elts = malloc(sz * n); if(list->part.elts == NULL) return -1; list->part.nelts = 0; list->part.next = NULL; list->ele_size = sz; list->nalloc = n; list->last = &(list->part); return 1;}static ngx_list_t* ngx_list_create(u_int sz,u_int n){ ngx_list_t* list = (ngx_list_t*) malloc(sizeof(ngx_list_t)); if(list == NULL) return NULL; if(ngx_list_init(list,sz,n) < 0){ free(list); return NULL; } return list;}static void* ngx_push_back(ngx_list_t* list){ void* elts; ngx_list_part_t* last; last = list->last; if(last->nelts == list->nalloc){ ngx_list_part_t *n = (ngx_list_part_t*) malloc(sizeof(ngx_list_part_t)); if(n == NULL){ return NULL; } n->elts = malloc(list->ele_size*list->nalloc); if(n->elts == NULL){ free(n); return NULL; } n->nelts = 0; n->next = NULL; last->next = n; list->last = n; last = n; } elts = (char*)(last->elts) + list->ele_size*last->nelts; last->nelts++; return elts;}typedef struct myElement{ int i; double j;} element;#define NELEM 5int main(){ ngx_list_t *mylist = ngx_list_create(sizeof(element), NELEM); for(int i =0; i < 2*NELEM; i++){ element* p = (element*)ngx_push_back(mylist); p->i = i; p->j = i; }}
代码只管分配内存,而没有管内存的回收,nginx中有专门的内存池帮助系统回收内存,
list 其实是很多页内存通过链表连接起来的,每一页的大小相同,当一页占满时,就向系统申请多一页,链在后面,
#include <stdio.h>#include <stdlib.h>typedef unsigned int u_int;typedef struct{ void* elts; u_int nelts; u_int size; u_int nalloc; //current reserved, nelts <= nalloc}ngx_array_t;static inline intngx_array_init(ngx_array_t* array,u_int sz,u_int nalloc){ array->nelts = 0; array->size = sz; array->nalloc =nalloc; array->elts = malloc( sz* nalloc); if(array->elts == NULL) return -1; return 1;}static ngx_array_t*ngx_array_create(u_int sz, u_int nalloc){ ngx_array_t* ret = (ngx_array_t*) malloc(sizeof(ngx_array_t)); if(ret == NULL) return NULL; if(ngx_array_init(ret,sz,nalloc) == -1){ free(ret); return NULL; } return ret;}static void* ngx_array_push(ngx_array_t *a){ if(a->nelts == a->nalloc){ u_int nelts = (a->nelts == 0)? 1 : 2*(a->nelts); void* new_nelts = realloc(a->elts,nelts); if(new_nelts == NULL) return NULL; a->elts = new_nelts; a->nalloc = nelts; } void* ret = (char*)a->elts + a->size*a->nelts; a->nelts++; return ret;}#define ARRAYSIZE 5typedef struct{ int i; double j;}element;static voidprintTheArray(ngx_array_t *a){ int i; element* p = NULL; int nelts = a->nelts; printf("the sapce is %d\n",a->nalloc); for(i = 0; i < nelts;i++){ p = (element*)((char*)a->elts + i*sizeof(element)); printf("the value i is%d\n",p->i); }}int main(){ ngx_array_t *array = ngx_array_create(sizeof(element),ARRAYSIZE); if(array == NULL) return 0; for(int i =0; i < ARRAYSIZE;i++){ element *p =(element*)ngx_array_push(array); p->i = i; p->j = i; } printTheArray(array); return 0;}
运行结果:
the sapce is 5the value i is0the value i is1the value i is2the value i is3the value i is4
array其实就是动态扩张的数据结构,每次内存不够用时,重新申请2倍的内存使用.跟STL的设计差不多.
阅读全文
0 0
- nginx源码阅读笔记.array和list数据结构
- Redis源码阅读笔记--六大数据结构和五大对象
- nginx 源码分析阅读笔记-进程管理
- Nginx 源码阅读笔记1 内存池
- Nginx 源码阅读笔记3 时间管理
- Nginx 源码阅读笔记4 启动流程
- Nginx 源码阅读笔记5 初始化 cycle
- Nginx 源码阅读笔记8 epoll 模块
- nginx array and list
- JDK源码阅读之List和AbstractSequentialList
- Fragment笔记和源码阅读
- nginx 数据结构之 array
- nginx源码阅读(一)
- 阅读 Nginx 源码
- 阅读nginx源码_win32
- nginx源码阅读
- STL源码阅读-list
- Java源码阅读-List
- python实现计数排序、桶排序、基数排序
- Volley报NullPointerException原因
- C语言中getopt()和getopt_long()函数的用法
- drop、truncate和delete的用法及区别
- localstorage存取json
- nginx源码阅读笔记.array和list数据结构
- XML之DOM思想的DOM4J解析器
- 文章标题
- jupyter notebook的安装与使用
- BZOJ 2618: [Cqoi2006]凸多边形(半平面交)
- ubuntu更新阿里源与桌面快捷操作
- 机器学习第4章第1节 : R语言基本语法及操作
- CF678E Another Sith Tournament(概率dp+状压dp)
- js之substr与substring的区别