Nginx底层基础数据结构

基础数据结构

ngx_int_t

32位操作系统4字节,64位操作系统8字节

解决跨平台以及,普通int类型在x86和x64操作系统上面是4字节,在类型转换时造成内存浪费(如在x64下面转换long类型)

typedef intptr_t        ngx_int_t;#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef __int32 intptr_t;
#endif

ngx_str_t

在Nginx的领域中,ngx_str_t结构就是字符串。ngx_str_t的定义如下:

ngx_str_t只有两个成员,其中data指针指向字符串起始地址,len表示字符串的有效长度。注意,ngx_str_t的data成员指向的并不是普通的字符串,
因为这段字符串未必会以’\0’作为结尾,所以使用时必须根据长度len来使用data成员。

typedef struct {size_t      len;u_char     *data;
} ngx_str_t;

ngx_list_t

ngx_list_t描述整个链表,而ngx_list_part_t只描述链表的一个元素。这里要注意的是,ngx_list_t不是一个单纯的链表,为了便于理解,我们姑且称它为存储数组的链表,什么意思呢?抽象地说,就是每个链表元素ngx_list_part_t又是一个数组,拥有连续的内存,它既依赖于ngx_list_t里的size和nalloc来表示数组的容量,同时又依靠每个ngx_list_part_t成员中的nelts来表示数组当前已使用了多少容量。因此,ngx_list_t是一个链表容器,而链表中的元素又是一个数组。事实上,ngx_list_part_t数组中的元素才是用户想要存储的东西,ngx_list_t链表能够容纳的元素数量由ngx_list_part_t数组元素的个数与每个数组所能容纳的元素相乘得到。

这样设计有什么好处呢?
  • 链表中存储的元素是灵活的,它可以是任何一种数据结构。
  • 链表元素需要占用的内存由ngx_list_t管理,它已经通过数组分配好了。
  • 小块的内存使用链表访问效率是低下的,使用数组通过偏移量来直接访问内存则要高效得多。

image-20240122214654294

成员以及成员意义
  • ngx_list_part_s:链表的每一个节点
    • elts:指向数组的起始地址。
    • nelts:已经使用的容量
    • next:下一个节点
  • ngx_list_t:链表类
    • part:首节点,注意:首节点存储的是一个结构体,而不是指针
    • last:指向最后一个节点
    • size:节点的elts数组中存储的数据类型的最大大小
    • nalloc:链表的数组元素一旦分配后是不可更改的。nalloc表示每个ngx_list_part_t数组的容量,即最多可存储多少个数据。
    • pool:所属内存池,链表中管理内存分配的内存池对象。用户要存放的数据占用的内存都是由pool分配的
typedef struct ngx_list_part_s  ngx_list_part_t;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;ngx_uint_t nalloc; ngx_pool_t *pool; 
} ngx_list_t;//创建链表
//n size分别对应ngx_list_t中的size和nalloc
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);//链表初始化,在ngx_list_create会调用,无需自己调用
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_table_elt_t

  • ngx_table_elt_t就是一个key/value对,ngx_str_t 类型的key、value成员分别存储的是名字、值字符串。

  • 显而易见,ngx_table_elt_t是为HTTP头部“量身订制”的,其中key存储头部名称(如Content-Length),value存储对应的值(如“1024”),

  • lowcase_key是为了忽略HTTP头部名称的大小写(例如,有些客户端发来的HTTP请求头部是content-length,Nginx希望它与大小写敏感的

  • Content-Length做相同处理,有了全小写的lowcase_key成员后就可以快速达成目的了),hash用于快速检索头部

typedef struct {ngx_uint_t        hash;//通过key value字符串计算出的hash值ngx_str_t         key;ngx_str_t         value;u_char           *lowcase_key;//存放的是本结构体中key的小写字母字符串
} ngx_table_elt_t;

ngx_buf_t

缓冲区ngx_buf_t是Nginx处理大数据的关键数据结构,它既应用于内存数据也应用于磁盘数据

ngx_buf_t是一种基本数据结构,本质上它提供的仅仅是一些指针成员和标志位。对于HTTP模块来说,需要注意HTTP框架、事件框架是如何设置和使用pos、last等指针以及如何处理这些标志位的,上述说明只是最常见的用法。(如果我们自定义一个ngx_buf_t结构体,不应当受限于上述用法,而应该根据业务需求自行定义。例如用一个ngx_buf_t缓冲区转发上下游TCP流时,pos会指向将要发送到下游的TCP流起始地址,而last会指向预备接收上游TCP流的缓冲区起始地址。)

成员以及成员意义
  • pos:指向从内存池里分配的内存。 pos为已扫描的内存端中,还未解析的内存的尾部,
  • last:last通常表示有效的内容到此为止
  • file_pos:将要处理的文件位置
  • file_last:截止的文件位置
  • start:指向ngx_buf_t的起始地址
  • end:与start成员对应,指向缓冲区内存的末尾
  • tag:表示当前缓冲区的类型,例如由哪个模块使用就指向这个模块ngx_module_t变量的地址
  • file:引用的文件 用于存储接收到所有包体后,把包体内容写入到file文件中,
  • shadow:当前缓冲区的影子缓冲区,该成员很少用到
  • temporary:临时内存标志位,为1时表示数据在内存中且这段内存可以修改
  • memory:标志位,为1时表示数据在内存中且这段内存不可以被修改
  • mmap:标志位,为1时表示这段内存是用mmap系统调用映射过来的,不可以被修改
  • recycled:标志位,为1时表示可回收利用,当该buf被新的buf指针指向的时候,就置1,
  • in_file:标志位,为1时表示这段缓冲区处理的是文件而不是内存,说明包体全部存入文件中,
  • flush:标志位,为1时表示需要执行flush操作 标示需要立即发送缓冲的所有数据;
  • sync:标志位,0同步,1异步
  • last_buf:标志位,表示是否是最后一块缓冲区,因为ngx_buf_t可以由ngx_chain_t链表串联起来,因此,当last_buf为1时,表示当前是最后一块待处理的缓冲区
  • last_in_chain:标志位,表示是否是ngx_chain_t中的最后一块缓冲区
  • last_shadow:标志位,表示是否是最后一个影子缓冲区,与shadow域配合使用。通常不建议使用它
  • temp_file:标志位,表示当前缓冲区是否属于临时文件
  • num:读取后端服务器包体分配的第几个buf
typedef void *            ngx_buf_tag_t;
typedef struct ngx_buf_s  ngx_buf_t;struct ngx_buf_s {//它的pos成员和last成员指向的地址之间的内存就是接收到的还未解析的字符流u_char          *pos;u_char          *last;//处理文件时,file_pos与file_last的含义与处理内存时的pos与last相同,off_t            file_pos;off_t            file_last;//如果ngx_buf_t缓冲区用于内存,那么start指向这段内存的起始地址u_char          *start;u_char          *end;ngx_buf_tag_t    tag;ngx_file_t      *file;ngx_buf_t       *shadow;unsigned         temporary:1; unsigned         memory:1;unsigned         mmap:1;unsigned         recycled:1; unsigned         in_file:1;unsigned         flush:1;unsigned         sync:1;unsigned         last_buf:1; unsigned         last_in_chain:1;unsigned         last_shadow:1; unsigned         temp_file:1;/* STUB */ int   num;
};

ngx_chain_t

ngx_chain_t是与ngx_buf_t配合使用的链表数据结构

buf指向当前的ngx_buf_t缓冲区,next则用来指向下一个ngx_chain_t。如果这是最后一个ngx_chain_t,则需要把next置为NULL。

struct ngx_chain_s {ngx_buf_t    *buf;ngx_chain_t  *next;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/753038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【贪心算法】Leetcode 55. 跳跃游戏 45. 跳跃游戏 I

【贪心算法】Leetcode 55. 跳跃游戏 45. 跳跃游戏 II Leetcode 55. 跳跃游戏解法1 贪心 Leetcode 45. 跳跃游戏I解法 贪心 Leetcode 55. 跳跃游戏 ---------------🎈🎈55. 跳跃游戏 题目链接🎈🎈------------------- 解法1 贪心…

SpringMVC结合设计模式:解决MyBatisPlus传递嵌套JSON数据的难题

🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…

Nginx指令配置大全

基本命令 nginx -t 检查配置文件是否有语法错误 nginx -s reload 热加载,重新加载配置文件 nginx -s stop 快速关闭 nginx -s quit 等待工作进程处理完成后关闭配置块介绍 全局块 全局块是默认配置文件从开始到events块之间的…

蓝桥杯算法练习系统—作物杂交【第十一届】【省赛】【C组】

问题描述 作物杂交是作物栽培中重要的一步。已知有 N 种作物(编号 1 至 N ),第 i 种作物从播种到成熟的时间为 Ti。 作物之间两两可以进行杂交,杂交时间取两种中时间较长的一方。如作物 A 种植时间为 5 天,作物 B 种植时间为 7 天&#xff0…

Spark杂谈

文章目录 什么是Spark对比HadoopSpark应用场景Spark数据处理流程什么是RDDSpark架构相关进程入门案例:统计单词数量Spark开启historyServer 什么是Spark Spark是一个用于大规模数据处理的统一计算引擎Spark一个重要的特性就是基于内存计算,从而它的速度…

[C++提高编程](一):模板----函数模板

目录 函数模板作用 函数模板的语法 注意事项 普通函数与函数模板的区别 普通函数与函数模板的调用规则 模板的局限性 案例--通用数组选择排序从大到小 模板是C中泛型编程的基础,一个模板就是一个创建类或函数的蓝图或者公式。 函数模板作用 建立一个通用函…

LSS (Lift, Splat, Shoot)

项目主页 https://nv-tlabs.github.io/lift-splat-shoot 图1:本文提出一种模型,给定多视角相机数据 (左), 直接在鸟瞰图 (BEV) 坐标系(右)中推理语义。我们展示了车辆分割 (蓝色),可驾驶区域 (橙色) 和车道分割 (绿色) 的结果。然…

【编程向导】JavaScript-基础语法-语句和声明一期讲解

文章目录 while 语句语法参数 示例代码示例 try-catch 语句catchfinally嵌套捕获异常标识符 throw 语句语法参数 示例代码示例抛出一个对象 while 语句 while 语句可以在某个条件表达式为真的前提下,循环执行指定的一段代码,直到那个表达式不为 true 时…

C语言项目:数组与函数实践:扫雷游戏

目录 目录: 1.扫雷游戏分析与设计 1.1扫雷游戏的功能说明: 1.1.1使用控制台实现经典扫雷的游戏 1.1.2游戏可以通过菜单实现继续玩或者退出游戏 1.1.3扫雷棋盘是9*9的格子 1.1.4默认随机布置10个雷 1.1.5 可以排查雷 2.扫雷游戏的代码实现 1.遇到的问题…

项目文章|真菌ChIP-seq+RNA-seq解析脱落酸生物合成的调控机制

组蛋白翻译后修饰是表观遗传调控的主要机制之一,已被证明在基因表达的调控中发挥重要作用,参与真菌发育、感染相关的形态发生、环境应激反应、次级代谢产物的生物合成和致病性。我们分享过不少真菌组蛋白修饰的文章,今天接着带来一篇利用ChIP…

Anaconda安装proplot库

看了一下Anaconda中的环境,现在我有4个,其中gee是一个虚拟环境 因此一般在prompt中装库时要先进入其中一个虚拟环境 conda activate geepip install proplot --no-deps下完了之后,发现版本不对应 conda install matplotlib3.4.3

软件开发项目管理/研发项目管理软件:国产EDA工具厂商行芯科技上线奥博思PowerProject项目管理软件平台

国内领先的EDA工具链提供商杭州行芯科技有限公司(以下简称:行芯科技)与北京奥博思软件技术有限公司达成战略合作,奥博思软件将基于PowerProject项目管理系统助力行芯科技实现研发项目的全生命周期管理,提升管理效能&am…

vue系列:使用vue3、ant-d,a-select下拉的搜索功能

背景 记录一下 大屏项目中&#xff0c;下拉数据过多&#xff0c;想使用下拉搜索功能&#xff1b; 输入汉字&#xff0c;匹配对应的项目&#xff1b; 解决方案 关键代码如下&#xff1a; a-select控件 <a-selectv-model:value"state.schemeInfo.monitorList"sho…

论文阅读:Face Deblurring using Dual Camera Fusion on Mobile Phones

今天介绍一篇发表在 ACM SIGGRAPH 上的文章&#xff0c;是用手机的双摄系统来做人脸去模糊的工作。这也是谷歌计算摄影研究组的工作。 快速运动物体的运动模糊在摄影中是一个一直以来的难题&#xff0c;在手机摄影中也是非常常见的问题&#xff0c;尤其在光照不足&#xff0c;…

短链码生成方案探讨思维链路

前段时间在做短链平台项目时&#xff0c;对短链码的生成进行了研究&#xff0c;我将思维活动和方案探讨过程进行了记录&#xff0c;文章没什么干货&#xff0c;都是思维过程。 短链码生成方式&#xff0c;应具备以下几个特点&#xff1a;生成性能强劲、碰撞概率低&#xff08;避…

jasypt加解密

项目中经常遇到jasypt加解密的配置文件&#xff0c;尤其是项目不是自己创建的时候&#xff0c;压根不知道加密的内容是什么&#xff0c;而配置文件中一般加密的也都是数据库或其他非结构型数据库的账号或密码&#xff0c;这时候想要看一下db的内容就非常的头疼&#xff0c;除了…

OSDI 2023

17th USENIX Symposium on Operating Systems Design and Implementation, OSDI 2023, Boston, MA, USA, July 10-12, 2023. 第17届USENIX操作系统设计与实现研讨会&#xff0c;OSDI 2023&#xff0c;2023年7月10-12日&#xff0c;美国马萨诸塞州波士顿。 1. Ship your Criti…

【爬虫】– 抓取原创力文档数据

使用RPA工具&#xff0c;实现针对于原创力中不可下载文档的抓取&#xff0c;可延用于其他类似文库 1 使用工具、环境 影刀RPA、WPS Office、谷歌浏览器&#xff08;非指定&#xff09; 2 代码流程 3 关键点 此方案只适合抓取非VIP即可预览全文的文档&#xff0c;抓取下来的数…

B007-springcloud alibaba 消息驱动 Rocketmq

目录 MQ简介什么是MQMQ的应用场景异步解耦流量削峰 常见的MQ产品 RocketMQ入门RocketMQ环境搭建环境准备安装RocketMQ启动RocketMQ测试RocketMQ关闭RocketMQ RocketMQ的架构及概念RocketMQ控制台安装 消息发送和接收演示发送消息接收消息 案例订单微服务发送消息用户微服务订阅…

(done) 解释 python3 torch.utils.data DataLoader

特别注意&#xff1a;DataLoader 返回的迭代器是无尽的&#xff0c;依据如下 (CHATGPT3.5) DataLoader 返回的迭代器默认情况下是无尽的&#xff0c;因为它会无限地循环遍历数据集&#xff0c;以提供批量的数据。在训练神经网络时&#xff0c;通常会使用无尽的迭代器来循环遍历…