nginx源码阅读笔记.array和list数据结构
2017-10-18 22:13
513 查看
1.概述
nginx中,array和list 的实现 和queue的实现不同,queue的实现是不依赖于具体的结构的,可以申明任何结构体只要该结构体中间含有queue的实例就可以将它们组织起来,那么queue的对象的内存分配需要(用户自己申请),在分配的包含queue的对象时已经分配好,
而list和array 的实现则时初始化一个list或者array, 自定义的结构的内存分配任务交给list和array完成,在向list 和array插入的时候就返回容器向内存申请的内存,用户直接可以在该地址上完成操作.
2.代码
代码只管分配内存,而没有管内存的回收,nginx中有专门的内存池帮助系统回收内存,
list 其实是很多页内存通过链表连接起来的,每一页的大小相同,当一页占满时,就向系统申请多一页,链在后面,
运行结果:
array其实就是动态扩张的数据结构,每次内存不够用时,重新申请2倍的内存使用.跟STL的设计差不多.
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 5 int 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 int ngx_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 5 typedef struct{ int i; double j; }element; static void printTheArray(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 5 the value i is0 the value i is1 the value i is2 the value i is3 the value i is4
array其实就是动态扩张的数据结构,每次内存不够用时,重新申请2倍的内存使用.跟STL的设计差不多.
相关文章推荐
- Nginx 源码分析-- ngx_array、ngx_list基本数据结构
- Nginx 源码阅读笔记5 初始化 cycle
- Nginx 源码阅读笔记2 原子变量与互斥锁
- NGINX----源码阅读---数据结构---配置文件相关
- Nginx 源码阅读笔记1 内存池
- ArrayList和LinkedList源码阅读笔记
- redis源码分析(八)、redis数据结构之压缩ziplist--------ziplist.c ziplist.h学习笔记
- Nginx 源码阅读笔记6 master 主循环
- Nginx 源码阅读笔记4 启动流程
- nginx 源码学习笔记(六)——nginx基本数据结构
- Redis源码阅读笔记—adlist
- nginx 源码学习笔记(八)——基本容器——array数组
- nginx 源码学习(六) 基本数据结构 ngx_array_t
- nginx 源码学习笔记(八)——基本容器——array数组
- nginx 源码学习笔记(八)——基本容器——array数组
- JDK 1.7源码阅读笔记(三)集合类之LinkedList
- Redis源码阅读笔记--六大数据结构和五大对象
- LinkedList源码阅读笔记
- Nginx源码阅读(ngx_list_t)
- Nginx 源码阅读笔记3 时间管理