其实Nginx自定义数据结构字符串(String) 数组(Array) 链表(List)的问题并不复杂,但是又很多的朋友都不太了解,因此呢,今天小编就来为大家分享Nginx自定义数据结构字符串(String) 数组(Array) 链表(List)的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
字符串(string) 数组(array) 链表(list) 队列(queue) 哈希(hash) 红黑树(rbtree) 基数树(radix_tree)
一、字符串
这个比较简单。其实和Redis的SDS设计类似。使用len字段保证字符串的二进制安全,解决字符串被’\0’截断的问题。
typedef 结构体{ size_t len; u_char *data;} ngx_str_t;Nginx为我们提供了字符串处理相关的宏
二、数组
Nginx 数组占用内存池上的连续空间。它存储的数据类型是确定的,容量是可以扩展的。这样的数组更容易使用。
文件名:ngx_array.h
typedef 结构{ void *elts; ngx_uint_t 内尔茨; size_t 尺寸; ngx_uint_t 分配; ngx_pool_t *池;} ngx_array_t;字段说明:
elts:数据块,指向实际存储的数据。
nelts:当前数组中存储的数据数量。
size:每个数据的大小。
nalloc:分配区域的大小,即当前数组可以存储的数据量。
pool:存储当前数组的内存池。
文件名:ngx_array.c
void * ngx_array_push(ngx_array_t *a){ void *elt, *new; size_t 尺寸; ngx_pool_t *p; if (a-nelts==a-nalloc) { /* 数组已满*/size=a-size * a -nalloc; p=池; if ((u_char *) a-elts + size==p-d.last p-d.last + a-size=p-d.end) { /* * 数组分配是池中的最后一个* 并且有空间用于新分配* /p-d.last +=a-size; a-nalloc++; } else { /* 分配一个新数组*/new=ngx_palloc(p, 2 * size); if (new==NULL) { 返回NULL; ngx_memcpy(新,a-elts,大小); a-elts=新的; a-nalloc *=2; } } elt=(u_char *) a-elts + a-size * a-nelts ; a-nelts++;返回埃尔特;}
当存放数组的内存池有剩余空间时,插入的数据直接在当前内存池中向后扩展;
当存储数组的内存池空间不足时,需要开辟新的内存空间,将数组数据分配到新的内存地址,以保证数组数据的连续性。
当数组使用完毕释放时,可以直接释放内存池上的空间,而不需要将内存返回给操作系统,从而保证了内存申请和释放的效率。
释放的内存仍然可以用于其他目的,实现内存复用,减少系统开销。
三、链表
链表和数组的区别在于它的数据在内存中不连续,但是它的插入动作的时间复杂度只有O(1)。
我们先看一下链表的结构
文件名:ngx_list.h
typedef struct ngx_list_part_s ngx_list_part_t; //链表struct ngx_list_part_s { void *elts; //指向节点的实际数据区域(该数据区域可以存储size大小的nalloc元素) ngx_uint_t nelts; //实际存储的元素数量(当前节点存储的元素数量) ngx_list_part_t *next; //指向下一个节点};字段说明:
elts:指向节点数据的实际存储区域。
nelts:当前链表节点上分配的数据数量。
next:指向链表的下一个节点。
一般链表每个Node存储一条数据,但是Nginx的链表在一个Node上存储多条数据。
//nginx链表结构不是简单的链表,而是数组的链表。 typedef 结构{ ngx_list_part_t *last; //指向链表的最后一个数组元素。 ngx_list_part_t 部分; //链表第一个数组元素size_t size; //每个元素的大小ngx_uint_t nalloc; //每个节点包含的数据数量ngx_pool_t *pool; //链表所在内存池} ngx_list_t;字段说明:
last:链表的最后一个节点。
部分:链表的第一个节点。
size:每个数据的大小。
nalloc:链表每个节点所包含的数据数量。
pool:链表头所在的内存池。
链表相关操作API包括:
//创建链表ngx_list_t * ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size) //向链表插入数据void * ngx_list_push(ngx_list_t *l) 在ngx_list_create 中,会调用ngx_list_init 来初始化链表。
链表初始化后,通过ngx_list_push函数将数据插入到链表中。该函数定义如下:
无效*ngx_list_push(ngx_list_t *l){ 无效*elt; ngx_list_part_t *最后;最后=l-最后; if (last-nelts==l-nalloc) { /* 最后一部分已满,分配新的列表部分*/last=ngx_palloc(l-pool, sizeof(ngx_list_part_t));如果(最后==NULL){返回NULL;最后elts=ngx_palloc(l-pool, l-nalloc * l-size); if (last-elts==NULL) { return NULL; }最后-nelts=0;上一个-下一个=NULL; l-最后一个-下一个=最后一个; l-最后=最后; }//如果当前节点有足够的空间,则只执行这2行Line elt=(char *) last-elts + l-size * last-nelts;最后-nelts++; return elt;} 不知道大家有没有注意到,插入链表时只传入一个链表指针,插入数组时也只传入一个链表指针。传入了数组指针,但没有传入要插入的数据。
这是因为上层的数据类型不确定,可以是任意数据类型,所以数据的拷贝分配就交给了上层,下层只负责分配空间。所以我们可以看到ngx_list_push和ngx_array_push的返回值都是void *来适应上层数据类型。
原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/126162.html
用户评论
余温散尽ぺ
这篇博文讲解了Nginx自定义数据结构的使用,感觉对提高nginx效率很有帮助!特别是字符串数组、链表的操作,之前都没接触过,看了博客后总算有所了解了。
有9位网友表示赞同!
毒舌妖后
终于有人科普Nginx自定义数据结构了!以前一直只是知道可以做一些扩展,一点都不知道具体怎么操作呢。这个String数组和链表的应用案例写的很实用,受益匪浅!
有17位网友表示赞同!
残留の笑颜
字符串数组、链表确实是很常用的数据结构,虽然nginx本身已经有了一些基础的数据处理方式,但自定义这部分还是很有必要的。希望以后能看到更多更深入的应用场景分析,比如如何结合特定的业务场景进行优化等等。
有17位网友表示赞同!
尘埃落定
作为一名新手,看了这篇博客后还是有点懵逼,感觉描述的太技术细节了,对于完全没有基础的人来说有些难以理解。
有6位网友表示赞同!
一别经年
字符串数组和链表的确很有用,但Nginx本身对内存管理的要求就非常严格了,自定义数据结构操作的时候要注意性能和稳定性问题,不要过度复杂化代码。
有17位网友表示赞同!
娇眉恨
这个博客讲的太浅层了!关于数据的插入、删除、查找效率等等都没深入分析,只描述了表面上的操作接口, 对于想要深究Nginx底层优化的研究者来说不太有价值。
有11位网友表示赞同!
一样剩余
感觉这篇文章很有用信息量很大,对提高Nginx性能有一定帮助。期待后续学习更高级的自定义数据结构!
有13位网友表示赞同!
拽年很骚
对新手来说这篇博客还是有点难理解,希望作者能添加一些更通俗易懂的解释和例子,比如用一些更直观的图示来辅助说明。
有18位网友表示赞同!
十言i
Nginx本身的数据结构就比较灵活,还能自定义扩展,真是太牛了!以后有机会我要学习一下如何自己编制这些自定义数据结构,提高nginx的功能!
有20位网友表示赞同!
葵雨
这篇博客讲的挺详细的,把字符串数组、链表这两种常用的数据结构分别讲解了一遍,还给了具体的Nginx例子,很有借鉴意义。
有6位网友表示赞同!
青楼买醉
其实Nginx在很多情况下都可以使用现有的模块来完成功能,除非你有非常特殊的业务需求,才需要自定义数据结构。不过学习这些技术总是有益的!
有5位网友表示赞同!
情如薄纱
感觉这个博客对Nginx开发者来说挺有用的,特别是想深入了解Nginx底层工作机制的人,可以从这篇文章开始学习!
有6位网友表示赞同!
揉乱头发
自定义数据结构虽然强大,但要注意代码的简洁性和可维护性,如果复杂度过高反而会增加代码调试难度!
有19位网友表示赞同!
素婉纤尘
nginx真是个高效强大的工具!希望以后能看到更多关于Nginx高级定制化技术的博客文章,比如使用自定义数据结构实现更复杂的并发处理等等。
有7位网友表示赞同!
莫名的青春
对于我这种做网站前端的来说,这篇博客的内容有点太深入理解了…
有14位网友表示赞同!
迷路的男人
字符串数组和链表都是常见的算法数据结构,学习一下确实很有帮助!这篇博客讲解得还不错,可以作为入门教程参考!
有13位网友表示赞同!
红尘烟雨
虽然Nginx本身已经强大,但自定义数据结构也是一门必备技能,这样才能更灵活的针对具体的业务需求进行优化!
有6位网友表示赞同!
墨城烟柳
希望作者以后能关注一下其他类型的自定义数据结构,比如树状、图之类的,这些更加复杂的数据结构在特定场景下也能发挥独特的作用呢!
有19位网友表示赞同!