Nginx:存储数组的链表
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx:存储数组的链表相关的知识,希望对你有一定的参考价值。
今天把昨天没铺开的几个数据结构全部铺开,明天上手高级数据结构。
我的困惑
这个链表我很喜欢,且这个构想在我的脑子里面存在很久了,但是一直没去实现。
它,是deque吗?deque,刚开始接触的时候有那么一丝欣喜,但是再进一步了解之后,嗯,大家不喜欢用是有原因的。
我一直没有去实现它,我不是一个喜欢一直拖着的人,没有去实现,肯定是有原因的。
这么一种数据结构,它存在的意义是什么呢?对于每一块内存,都要专门开辟一个位置来记录它的空间,说是插入效率会比较高,但是真的能比普通数组高到哪里去呢?说是查询效率比较高,又能比链表高到哪里去?
这些问题我一直没有想明白,所以就不冒冒失失去实现了。
今天我就来为这些问题,找到一个出路!
存储数组的链表
typedef struct ngx_list_part_s ngx_list_part_t;
//节点
/*
每个链表元素ngx_list_part_t又是一个数组,拥有连续的内存,
它既依赖于ngx_list_t里的size和nalloc来表示数组的容量,
同时又依靠每个ngx_list_part_t成员中的nelts来表示数组当前已使用了多少容量。
*/
struct ngx_list_part_s {
void *elts; //指向数组的起始地址
ngx_uint_t nelts; //表示数组中已经使用元素数量
ngx_list_part_t *next; //下一个链表元素的地址
};
//链表
typedef struct {
ngx_list_part_t *last; //指向最后一个数组元素
ngx_list_part_t part; //首元素
size_t size; //限制每个数组元素占用空间大小,也就是用户要存储的一个数据所 占用的字节数必须小于或等于size。
ngx_uint_t nalloc; //最多可存储数据数
ngx_pool_t *pool; //管理内存分配的内存池对象
} ngx_list_t;
这个跟deque有点像的东西我想实现它很久了,没想到在这里看到了。
设计优点
1、通用链表
2、小块的内存使用链表访问效率是低下的,使用数组通过偏移量来直接访问内存则要高 效得多。
配备方法
在 ngx_list 类里面就给了这几个方法,也没有什么删查改,呃呃呃。真就给了这几个而已。
//用于创建新的链表
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);
//用于初始化一个已有的元素
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size);
//添加元素
void *ngx_list_push(ngx_list_t *list);
ngx_list_create
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
ngx_list_t *list;
list = ngx_palloc(pool, sizeof(ngx_list_t));
if (list == NULL) {
return NULL;
}
if (ngx_list_init(list, pool, n, size) != NGX_OK) {
return NULL;
}
return list;
}
ngx_list_create返回新创建的链表地址,如果创建失败,则返回NULL空指针。ngx_list_create 被调用后至少会创建一个数组(不会创建空链表),其中包含n个大小为size字节的连续内存 块,也就是ngx_list_t结构中的part成员。
ngx_list_init
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
list->part.elts = ngx_palloc(pool, n * size);
if (list->part.elts == NULL) {
return NGX_ERROR;
}
list->part.nelts = 0;
list->part.next = NULL;
list->last = &list->part;
list->size = size;
list->nalloc = n;
list->pool = pool;
return NGX_OK;
}
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->elts = ngx_palloc(l->pool, l->nalloc * l->size);
if (last->elts == NULL) {
return NULL;
}
last->nelts = 0;
last->next = NULL;
l->last->next = last;
l->last = last;
}
elt = (char *) last->elts + l->size * last->nelts;
last->nelts++;
return elt;
}
哎,权当记录吧,希望读到后面,能慢慢清晰这个链表在nginx中的应用吧,这篇,终究缺了个点睛之笔。
我全局搜索了源码,其实用到的地方也不多。。。
以上是关于Nginx:存储数组的链表的主要内容,如果未能解决你的问题,请参考以下文章