Nginx源代码分析--基本数据结构--hash

Delta-Sigma调制(DSM)技术 前言 数字信号处理和通信系统的性能很大程度上受到了模拟信号到数字信号转换接口——ADC的精度和分辨率的限制。而传统的线性脉冲编码调制(PCM)ADC受到了制造工艺的限制,无法达到很高的分辨率。但基于Delta-Sigma调制技术的ADC可以在现有工艺下实现高分辨率(大于16位),同时由于结构简单,所以易于实现。低成本高性能使得Delta-Sigma调制技术得到了广泛的应用。 Delta-Sigma型ADC的结构原理图如下图所示: 它最大的优势在于仅用1位ADC进行数据转换,同时其模拟电路部分结构简单不需要 阅读详情

我们来看一下wildcard初始化函数。

 

//函数ngx_int_t

 

//ngx_array_s结构体

 

 

 

//elts是指向内存池中的存储元素的指针。内存池pool需要进行元素对齐等,所以这个值不等于pool

//nelts是当前有的元素个数

//size是每个元素大小

//nalloc是元素的多少

//pool是内存池的指针

 

 

struct ngx_array_s {
    void        *elts;
    ngx_uint_t   nelts;
    size_t       size;
    ngx_uint_t   nalloc;
    ngx_pool_t  *pool;
};

 

 

 

 

 

 

//内联函数,进行数组初始化,其实是分配某个数量的元素的内存,以便于压栈等操作

 

 

//参数,数组管理结构体、内存池、元素多少,每个元素大小

 

 

static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    /*
     * set "array->nelts" before "array->elts", otherwise MSVC thinks
     * that "array->nelts" may be used without having been initialized
     */

    array->nelts = 0;
    array->size = size;
    array->nalloc = n;
    array->pool = pool;

    array->elts = ngx_palloc(pool, n * size);
    if (array->elts == NULL) {
        return NGX_ERROR;
    }

    return NGX_OK;
}

 

 

 

 

 

 

 

 

 

//函数ngx_hash_wildcard_init

//这段代码,由于我从来没看过wildcard的相关代码,所以另我相当恶心

 

//一起看看吧

 

 

ngx_int_t
ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
    ngx_uint_t nelts)
{
    size_t                len, dot_len;
    ngx_uint_t            i, n, dot;
    ngx_array_t           curr_names, next_names;
    ngx_hash_key_t       *name, *next_name;
    ngx_hash_init_t       h;
    ngx_hash_wildcard_t  *wdc;

 

    //在hinit->temp_pool中开辟内存,并分配nelts个大小为ngx_hash_key_t的元素的内存空间,对齐后,将指针赋给curr_names

    //该元素数组指针即 curr_names

 

 

    if (ngx_array_init(&curr_names, hinit->temp_pool, nelts,
                       sizeof(ngx_hash_key_t))
        != NGX_OK)
    {
        return NGX_ERROR;
    }

 

    //同样在hinit->temp_pool中开辟内存,分配nelts个大小为ngx_hash_key_t的元素的内存空间,对齐后,将指针赋给next_names

    //该元素数组指针即 next_names


    if (ngx_array_init(&next_names, hinit->temp_pool, nelts,
                       sizeof(ngx_hash_key_t))
        != NGX_OK)
    {
        return NGX_ERROR;
    }

 

 

 

   //对于整个数组

 

    for (n = 0; n < nelts; n = i) {

#if 0
        ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                      "wc0: /"%V/"", &names[n].key);
#endif

 

        //标识
        dot = 0;
        //如果这个数组的元素中,有dot则,赋dot为1,并跳出这个检测数组元素中是否有dot的循环,当前的len则是从数组开始到数组中的  

        //dot。
        for (len = 0; len < names[n].key.len; len++) {
            if (names[n].key.data[len] == '.') {
                dot = 1;
                break;
            }
        }

        //curr_names的指针发生移动,以便于给当前元素赋值。也就是“压栈”操作
        name = ngx_array_push(&curr_names);
        if (name == NULL) {
            return NGX_ERROR;
        }
                 //压栈操作的赋值代码,将names这个数组,的当前元素的值填充到name这个数组中,包括计算这个当前元素的key_hash的值
        name->key.len = len;
        name->key.data = names[n].key.data;
        name->key_hash = hinit->key(name->key.data, name->key.len);
        name->value = names[n].value;

#if 0
        ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                      "wc1: /"%V/" %ui", &name->key, dot);
#endif

 

        //数组中dot后其余部分的开始


        dot_len = len + 1;


        //如果dot==1,则说明数组其余部分第一个是dot,应该将len+1指向dot后第一个字符
        if (dot) {
            len++;
        }

 

 

       //初始化next_names指向的元素的实际个数为0

 

        next_names.nelts = 0;

 

        //如果names中的元素长度与当前长度不等,说明确实有dot。


        if (names[n].key.len != len) {

              //把这个压入next_names栈中

            next_name = ngx_array_push(&next_names);
            if (next_name == NULL) {
                return NGX_ERROR;
            }


           //得到新的字串的长度
            next_name->key.len = names[n].key.len - len;
           //新的字串的指针

           next_name->key.data = names[n].key.data + len;
           //新的字串的hash值

           next_name->key_hash = 0;

            //新的字串的值
           next_name->value = names[n].value;

#if 0
            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                          "wc2: /"%V/"", &next_name->key);
#endif
        }

 

        //比较当前names[n]的值的数据是否有和n+1到nelts的元素的值相同的
        for (i = n + 1; i < nelts; i++) {

            //如果names[n]的key值的数据和names[i]的key的数据相同不相同,则跳出循环。

            if (ngx_strncmp(names[n].key.data, names[i].key.data, len) != 0) {
                break;
            }

             //到这,意味着key数据值相同

              //如果dot==0并且names[i]的key的长度大于len并且names[i]的key的数据不是dot(.)则退出循环

            if (!dot
                && names[i].key.len > len
                && names[i].key.data[len] != '.')
            {
                break;
            }

            //到这意味着dot==1,并且names[i]的后边也有字符。则将next_names压入栈,即names[i]与names[n]处理相同


            next_name = ngx_array_push(&next_names);
            if (next_name == NULL) {
                return NGX_ERROR;
            }
             //进行赋值与names[n]的相同


            next_name->key.len = names[i].key.len - dot_len;
            next_name->key.data = names[i].key.data + dot_len;
            next_name->key_hash = 0;
            next_name->value = names[i].value;

#if 0
            ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
                          "wc3: /"%V/"", &next_name->key);
#endif
        }

 

 

 

 

        //如果当前没有执行过push_array_push操作,也就是dot后边没有元素

       //则意味着curr_names中已经不含有dot。

 

       //递归调用,对next_names进行

 

        if (next_names.nelts) {

            h = *hinit;
            h.hash = NULL;

            if (ngx_hash_wildcard_init(&h, (ngx_hash_key_t *) next_names.elts,
                                       next_names.nelts)
                != NGX_OK)
            {
                return NGX_ERROR;
            }

 

             //没看明白。。。。。。。。。。。。。。。。。。。。。。。。。。。。

 

            wdc = (ngx_hash_wildcard_t *) h.hash;

            if (names[n].key.len == len) {
                wdc->value = names[n].value;
            }

            name->value = (void *) ((uintptr_t) wdc | (dot ? 3 : 2));

        } else if (dot) {
            name->value = (void *) ((uintptr_t) name->value | 1);
        }
    }

 

 

  //最后,所有不含dot的元素都在curr_names中了,进行初始化hinit。

    if (ngx_hash_init(hinit, (ngx_hash_key_t *) curr_names.elts,
                      curr_names.nelts)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    return NGX_OK;
}

UG NX 12.0零基础实战:从草图绘制到三维建模全流程解析 本文详细解析UG NX 12.0从草图绘制到三维建模的全流程,适合零基础用户快速掌握这款工业设计软件。内容涵盖界面设置、基础操作、草图技巧、拉伸旋转建模、布尔运算等核心功能,并通过机械零件实战案例演示完整设计流程,帮助读者系统学习UG NX 12.0的工业设计应用。 阅读详情

相关推荐

基于Unidbg的小红书加密协议动态分析与算法还原实战

在移动应用安全领域,加密协议与签名机制是保障数据传输安全、实现客户端身份验证的核心技术。其原理通常涉及哈希算法、对称/非对称加密以及自定义的混淆逻辑,旨在防止请求被篡改或重放。理解这些协议对于安全研究、风控策略制定及合规的数据交互分析具有重要价值。在实际的工程实践中,面对高度混淆和加固的Native代码(SO库),传统的静态分析往往难以深入。此时,沙盒模拟执行技术提供了一种动态、可控的分析方案。通过搭建一个虚拟的移动应用运行环境,研究人员可以在无需真机、规避反调试机制的情况下,完整地追踪和观察加密算法的执行

weixin_29315091的博客 323

Nginx源代码分析-基本数据结构

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34163741的博客 304

用FPGA驱动WS2812B点阵,手把手教你实现动态文字显示(附完整Verilog代码)

本文详细介绍了如何使用FPGA驱动WS2812B点阵实现动态文字显示,包括硬件连接、Verilog代码实现和动态效果设计。通过精确的时序控制和数据处理,读者可以掌握FPGA与WS2812B的交互技术,并实现炫酷的显示效果。附完整Verilog代码,适合硬件爱好者和工程师参考实践。

weixin_30482383的博客 668

Nginx高效数据结构(4)——Hash表(ngx_hash_t)

Nginx是我们学习编程的一个非常有参考价值的开源项目。良好的编码风格,高效的数据结构、架构设计。

JK-Cool的博客 1151

Python实战:用Sinkhorn算法搞定最优传输问题(附完整代码)

本文详细介绍了如何使用Python实现Sinkhorn算法解决最优传输问题,包括算法原理、关键步骤和完整代码示例。通过实际案例(如图像颜色迁移)展示其高效性和稳定性,适合机器学习开发者和数据科学家应用于分布匹配等场景。

weixin_30879169的博客 96

置换矩阵、转置矩阵以及向量空间、子空间

置换矩阵、转置矩阵以及向量空间、子空间导读置换矩阵 导读 MIT矩阵分析课程之后的的二篇笔记。

qq_44677482的博客 1672

负载均衡一致性哈希算法实现 | nginx 负载均衡一致性哈希源码分析 | ngx_http_upstream_consistent_hash_module 源码分析

​ 理解七层反向代理的负载均衡 Nginx 中使用的的一致性哈希算法。开头只是讲一些没用的东西,后面主要是分析 Nginx 的 O(1) 时间复杂度的一致性哈希负载均衡的模块源代码实现,顺便了解一下 nginx 模块开发(参考Development guide (nginx.org) 中的 load balancing 部分)的大致样子。

锐龙处理器 2356

告别图像畸变:手把手教你用HALCON的`gen_image_to_world_plane_map`做高精度视觉测量

本文详细解析了HALCON的`gen_image_to_world_plane_map`算子在工业视觉测量中的应用,通过精确的几何变换消除透视畸变,提升测量精度。文章涵盖相机标定、世界坐标系建立、实战应用及性能优化,适用于液晶屏质检、金属板检测等场景,帮助工程师实现高精度视觉测量。

weixin_28718487的博客 421

菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)

菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.youkuaiyun.com/chen19870707 Date:Octo...

chuozhi7142的博客 161

一桶令牌的时间账本:四类限流算法的边界推演与Guava RateLimiter源码精读

限流的难点不在背出算法名,而在算清每一笔账:按哪一秒计数、超额请求排队还是拒绝、空闲后能否突发、集群总量如何约束。本文在可复现的虚拟时间实验台上对比固定窗口、滑动窗口、漏桶与令牌桶,实测边界双倍突发与分桶滑动的真实上界,拆解Nginx limit_req的千分位记账与延迟机制,纠正Resilience4j常被误称漏桶的说法,并逐行精读Guava SmoothRateLimiter的预消费、懒惰补账与预热积分,复刻迷你限流器与其完成七万次零差异对账,最后给出集群配额、分层防护与参数确定的方法。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 86万+

使用Simulink来模拟多旋翼无人机在风扰动条件下的飞行情况,并分析其稳定性

本教程详细介绍了使用Simulink进行多旋翼无人机风扰动稳定性分析的完整流程。首先构建包含飞行器动力学模型、控制系统和环境模拟模块的系统框架,重点讲解简化动力学方程的实现方法。随后指导设计PID控制器来维持姿态稳定,并添加随机风扰动模型模拟环境干扰。通过设置输入信号和输出显示,最终实现对不同风速条件下无人机控制性能的评估。该实例为无人机控制系统设计提供了实用的仿真方法,强调利用MATLAB工具进行可视化分析和参数优化,以提高系统抗干扰能力和稳定性。

amy_mhd的博客 418

Nginx基本数据结构之ngx_hash_t

ngx_hash_t是nginx自己的hash表的实现。定义和实现位于src/core/ngx_hash.h|c中。ngx_hash_t的实现也与数据结构教课书上所描述的hash表的实现是大同小异。对于常用的解决冲突的方法有线性探测,二次探测和开链法等。ngx_hash_t使用的是最常用的一种,也就是开链法,这也是STL中的hash表使用的方法。 但是ngx_hash_t的实现又有其几个显著

wangpengqi的专栏 1676

SCADA|用KingSCADA实现设备台账的查询功能

以上为用KingSCADA实现设备台账的查询功能,另外还有一些细节功能,比如当点击增加按钮时弹出的信息窗口内的信息希望是在选中的某行信息,只要找到差不多的设备,修改个别参数即可,避免增加时弹出空白页,所有信息都需要填写。以上为实现设备台账查询的最简单实现,实际项目中可能会更复杂,你做过哪些设备台账或相关的功能,有比较好的创意或高难度功能方法,欢迎在留言区评论,或在交流群探讨,互通有无,共同进步。首先完成界面的组态工作,主要是通过查询按钮,查询SQLServer数据库的设备台账数据,然后填充到报表内。

做有价值的事,积累有价值的笔记! 475

nginx源码分析—hash结构ngx_hash_t

Content 0.序 1.hash结构 1.1ngx_hash_t结构 1.2ngx_hash_init_t结构 1.3ngx_hash_key_t结构 1.4hash的逻辑结构 2.hash操作 2.1NGX_HASH_ELT_SIZE宏 2.2hash函数 2.3hash初始化 2.4hash查找 3.一个例子 3.1代码 3.2如何编译 3.3运行结果 3....

有趣的人生 一半是山川湖海 一半是初心情怀 941

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Nginx基本数据结构

话说学习一种编程语言,例如C语言,我们首先学的也是数据结构,这是以后开发程序的关键。为了更好更方便的开发Nginx,Nginx自己实现了很多适合nginx的数据结构。 Nginx中的数组   ngx_array_s是Nginx中的数组,原型为ngx_array_t。 typedef struct { void *elts; //指

把握自己。 2204

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

菜鸟nginx源代码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)

  菜鸟nginx源代码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)   Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.youkuaiyun.com/chen19870707 Date:October 31h, 2014   1.哈希表ngx_hash_t的优势和特点 哈希表是...

weixin_34324081的博客 233

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

nginx hash源码分析

HASH是NGINX核心数据结构之一.见几个链接.分析的很详细 1.http://www.linuxidc.com/Linux/2012-08/67040.htm 2.http://www.oschina.net/question/234345_42065 3.http://blog.youkuaiyun.com/lifeibo/article/details/5897126 4.http://cod...

黑暗遊侠 207

边缘AI计算芯片与本地推理:从算力下沉到模型部署的完整实践

边缘计算与人工智能的结合正在重塑设备端的智能能力,其核心在于将推理任务从云端下沉到数据源头,解决时延、带宽、隐私与成本四大痛点。边缘AI计算芯片通过NPU专用架构在有限功耗内实现高效能比,而内存带宽与数据复用则成为决定实际性能的关键因素。从模型选型、INT8量化校准到工具链适配,本地AI推理是一条涉及算法、硬件与系统协同的工程链路。本文基于真实项目经验,梳理了算力估算公式、芯片选型优先级及部署中的常见陷阱,为嵌入式开发、算法部署与产品评估提供可复用的技术骨架,帮助读者在安防、工业视觉等场景中稳健落地边缘AI

weixin_33829657的博客 410

Nginx 读源代码 需要哪些技能 和基础

1.推理2.

hxsln11的博客 507

菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上)[转]

菜鸟nginx源码剖析数据结构篇(六) 哈希表 ngx_hash_t(上) Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.youkuaiyun.com/chen19870707 Date:October 31h, 2014 1.哈希表ngx_hash_t的优势和特点 哈希表是...

weixin_30677475的博客 100
上一篇: Nginx源代码分析--基本数据结构--hash
下一篇: Nginx源代码分析--基本数据结构--hash
IterZebra
博客等级 码龄16年 56粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值