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;
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Canal实现mysql与缓存同步

什么是Canal Canal是阿里巴巴旗下的一款开源项目, 基于java开发. Canal是基于mysql的主从同步来实现的. github地址: https://github.com/alibaba/canal Canal把自己伪装成MySQL的一个slave节点, 从而监听master的binary log变化. 再把得到的变化信息通知给Canal的客户端, 进而…

vue3 element plus 上传下载

文章目录 上传下载 上传 /* html */ <el-upload v-model"fileId" class"avatar-uploader" ref"exampleUploadRef" :file-list"fileList" :show-file-list"false" action"/ys-three-year/ThreeReport/uploadFile&q…

Python从0到100(五):Python分支结构和循环结构

一、分支结构&#xff1a; Python中的分支结构和循环结构是编写程序时常用的控制结构。在Python中&#xff0c;分支结构通过if、elif和else关键字来实现条件判断。在使用if语句时&#xff0c;程序会根据条件表达式的真假执行相应的代码块。 if condition1:# 如果条件1为真&am…

YOLOv5改进 | 图像去雾 | 利用图像去雾网络UnfogNet辅助YOLOv5进行图像去雾检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用UnfogNet超轻量化图像去雾网络,我将该网络结合YOLOv5针对图像进行去雾检测(也适用于一些模糊场景),我将该网络结构和YOLOv5的网络进行结合同时该网络的结构的参数量非常的小,我们将其添加到模型里增加的计算量和参数量基本可…

每天一点正压采样器小知识

只要你奔跑&#xff0c;这个世界就会跟着你奔跑&#xff0c; 只要你停驻&#xff0c;这个世界就会舍弃你独自奔跑&#xff0c; 唯有你确定一个方向&#xff0c;使劲的跑起来&#xff0c; 这个世界会为你而让路。 每天一点正压采样器小知识 该采样器活赛与气筒采用全金属密封&am…

操作系统知识-存储管理+文件管理管理-嵌入式系统设计师备考笔记

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记&#xff0c;未经本人许可&#xff0c;请勿转载&#xff0c;如发现本笔记内容的错误还望各位不吝赐教&#xff08;笔记内容可能有误怕产生错误引导&#xff09;。 本章的主要内容见下图&#xff1a; 1、存储管理&#…

[c++]内存管理

1. C/C内存分布 我们先来看下面的一段代码和相关问题 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1; int num1[10] { 1, 2, 3, 4 }; char char2[] "abcd"; const char* pChar3 "abcd"; …

Redis 八种常用数据类型详解

夯实基础&#xff0c;这篇文章带着大家回顾一下 Redis 中的 8 种常用数据类型&#xff1a; 5 种基础数据类型&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;散列&#xff09;、Zse…

想进阿里?先搞懂Spring Bean的循环依赖!

如有疑问或者更多的技术分享,欢迎关注我的微信公众号“知其然亦知其所以然”! 嗨,小伙伴们!我是小米,你们的技术分享小助手!今天我们要聊的话题可是技术圈内颇为热门的“阿里巴巴面试题:Spring的循环依赖”哦!相信很多小伙伴都会在技术面试中遇到类似的问题,没错,循…

QT网络编程之获取本机网络信息

一.概述 查询一个主机的MAC地址或者IP地址是网络应用中常用到的功能&#xff0c;Qt提供了QHostInfo和QNetworkInterface 类可以用于此类信息的查询 1.QHostInfo 类&#xff08;显示和查找本地的信息&#xff09; 2.QNetworkInterface 类&#xff08;获得应用程序上所在主机的…

8.JavaWebHTML标签与CSS页面美化和布局控制

目录 导语&#xff1a; 一、HTML表单标签 二、CSS页面美化和布局控制 结语&#xff1a; 导语&#xff1a; 在Web开发中&#xff0c;HTML和CSS是两个不可或缺的技术。HTML&#xff08;HyperText Markup Language&#xff09;用于构建网页的结构&#xff0c;而CSS&#xff08…

【送书福利第五期】:ARM汇编与逆向工程

文章目录 &#x1f4d1;前言一、ARM汇编与逆向工程1.1 书封面1.2 内容概括1.3 目录 二、作者简介三、译者介绍&#x1f324;️、粉丝福利 &#x1f4d1;前言 与传统的CISC&#xff08;Complex Instruction Set Computer&#xff0c;复杂指令集计算机&#xff09;架构相比&#…

RabbitMQ的幂等性、优先级队列和惰性队列

文章目录 前言一、幂等性1、概念2、消息重复消费3、解决思路4、消费端的幂等性保障5、唯一 ID指纹码机制6、Redis 原子性 二、优先级队列1、使用场景2、如何添加3、实战 三、惰性队列1、使用场景2、两种模式3、内存开销对比 总结 前言 一、幂等性 1、概念 2、消息重复消费 3、…

day12-SpringBootWeb 登录认证

一、登录功能 Slf4j RestController public class LoginController {Autowiredprivate EmpService empService;PostMapping("/login")public Result login(RequestBody Emp emp){log.info("员工登录: {}", emp);Emp e empService.login(emp);//登录失败, …

2024考研国家线公布,各科分数线有哪些变化?考研国家线哪些涨了,哪些跌了?可视化分析告诉你

结论在文章结尾 2024考研国家线 一、近五年国家线趋势图-学术硕士 文学 管理学 工学照顾专业 体育学 交叉学科 军事学 历史学 理学 享受少数名族照顾政策的考生 中医类照顾专业 教育类 艺术类 医学 工学 哲学 法学 农学 经济学 二、近五年国家线趋势图-专业硕士 中医 应用心理 …

S3fd: Single shot scale-invariant face detector

目录 摘要一、介绍二、相关工作三、单镜头尺度不变人脸检测器3.1. Scale-equitable框架3.2. 尺度补偿锚匹配策略3.3. 最大输出背景标签3.4 训练4.实验4.1. 模型分析4.2. 基准评价4.3 推理时间 5 结论 摘要 本文提出了一种实时人脸检测器&#xff0c;称为单镜头尺度不变人脸检测…

判断素数(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int value 0;int i 2;int result 0;//循环获取用户值并判断值是否符合要求&#xff1b;while (1){//提示用户值需要满…

STM32中freertos任务不能调度的原因解决

本文是项目中的定位问题&#xff0c;如果定位到同样问题&#xff0c;可以按下面方法解决。 问题定位 这行assert代码主要判断系统中最大中断优先级数量是否等于内核中断优先级&#xff0c;实际意思就是要求内核中断优先级为系统最低优先级&#xff08;freertos中0为最高优先级…

文章类型分类项目

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 项目背景 在数据科学和机器学习的领域中&#xff0c;文本分析一直是一个引人注目的话题。这个项目的核心挑战是利用机器学习技术&#xff0c;根…

数据结构.pta测试二

#include<iostream> using namespace std; typedef struct node {int data;node* next; }*List;List listPoduce() {int a;List L;node * r, * new0;//创建指针L new node();//分配空间r L;cin >> a;while (a ! -1){new0 new node();new0->data a;r->nex…