Nginx 源码完全剖析(10)ngx_radix_tree
ngx_radix_tree.h
#define NGX_RADIX_NO_VALUE (uintptr_t) -1
typedef struct ngx_radix_node_s ngx_radix_node_t;
struct ngx_radix_node_s {
ngx_radix_node_t *right;
ngx_radix_node_t *left;
ngx_radix_node_t *parent;
uintptr_t value;
};
typedef struct {
ngx_radix_node_t *root;
ngx_pool_t *pool;
ngx_radix_node_t *free; // 空闲的节点由free开始连成一个链表,节点间通过right指针连接
char *start;
size_t size;
} ngx_radix_tree_t;
ngx_radix_tree.c
static void *ngx_radix_alloc(ngx_radix_tree_t *tree);
ngx_radix_tree_t *
ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate)
{
uint32_t key, mask, inc;
ngx_radix_tree_t *tree;
tree = ngx_palloc(pool, sizeof(ngx_radix_tree_t));
if (tree == NULL) {
return NULL;
}
tree->pool = pool;
tree->free = NULL;
tree->start = NULL;
tree->size = 0;
tree->root = ngx_radix_alloc(tree);
if (tree->root == NULL) {
return NULL;
}
tree->root->right = NULL;
tree->root->left = NULL;
tree->root->parent = NULL;
tree->root->value = NGX_RADIX_NO_VALUE;
if (preallocate == 0) {
return tree;
}
if (preallocate == -1) {
switch (ngx_pagesize / sizeof(ngx_radix_tree_t)) {
case 128:
preallocate = 6;
break;
case 256:
preallocate = 7;
break;
default:
preallocate = 8;
}
}
mask = 0;
inc = 0x80000000;
while (preallocate--) {
key = 0;
mask >>= 1;
mask |= 0x80000000;
do {
if (ngx_radix32tree_insert(tree, key, mask, NGX_RADIX_NO_VALUE)
!= NGX_OK)
{
return NULL;
}
key += inc;
} while (key);
inc >>= 1;
}
return tree;
}
ngx_int_t
ngx_radix32tree_insert(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
uintptr_t value)
{
uint32_t bit;
ngx_radix_node_t *node, *next;
bit = 0x80000000;
node = tree->root;
next = tree->root;
while (bit & mask) {
if (key & bit) {
next = node->right;
} else {
next = node->left;
}
if (next == NULL) {
break;
}
bit >>= 1;
node = next;
}
if (next) {
if (node->value != NGX_RADIX_NO_VALUE) {
return NGX_BUSY;
}
node->value = value;
return NGX_OK;
}
while (bit & mask) {
next = ngx_radix_alloc(tree);
if (next == NULL) {
return NGX_ERROR;
}
next->right = NULL;
next->left = NULL;
next->parent = node;
next->value = NGX_RADIX_NO_VALUE;
if (key & bit) {
node->right = next;
} else {
node->left = next;
}
bit >>= 1;
node = next;
}
node->value = value;
return NGX_OK;
}
// 节点从 Radix 树中删除后,会放入到 free 链表中
ngx_int_t
ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask)
{
uint32_t bit;
ngx_radix_node_t *node;
bit = 0x80000000;
node = tree->root;
while (node && (bit & mask)) {
if (key & bit) {
node = node->right;
} else {
node = node->left;
}
bit >>= 1;
}
if (node == NULL) {
return NGX_ERROR;
}
if (node->right || node->left) {
if (node->value != NGX_RADIX_NO_VALUE) {
node->value = NGX_RADIX_NO_VALUE;
return NGX_OK;
}
return NGX_ERROR;
}
for ( ;; ) {
if (node->parent->right == node) {
node->parent->right = NULL;
} else {
node->parent->left = NULL;
}
node->right = tree->free;
tree->free = node;
node = node->parent;
if (node->right || node->left) {
break;
}
if (node->value != NGX_RADIX_NO_VALUE) {
break;
}
if (node->parent == NULL) {
break;
}
}
return NGX_OK;
}
uintptr_t
ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key)
{
uint32_t bit;
uintptr_t value;
ngx_radix_node_t *node;
bit = 0x80000000;
value = NGX_RADIX_NO_VALUE;
node = tree->root;
while (node) {
if (node->value != NGX_RADIX_NO_VALUE) {
value = node->value;
}
if (key & bit) {
node = node->right;
} else {
node = node->left;
}
bit >>= 1;
}
return value;
}
static void *
ngx_radix_alloc(ngx_radix_tree_t *tree)
{
char *p;
if (tree->free) {
p = (char *) tree->free;
tree->free = tree->free->right;
return p;
}
if (tree->size < sizeof(ngx_radix_node_t)) {
tree->start = ngx_pmemalign(tree->pool, ngx_pagesize, ngx_pagesize);
if (tree->start == NULL) {
return NULL;
}
tree->size = ngx_pagesize;
}
p = tree->start;
tree->start += sizeof(ngx_radix_node_t);
tree->size -= sizeof(ngx_radix_node_t);
return p;
}
-
转载请注明来自钟超的CSDN博客:Blog.CSDN.net/Poechant
-
分享到:
相关推荐
ngx_http_proxy_connect_module是一个针对Nginx服务器的第三方模块,主要功能是支持HTTP代理的"CONNECT"方法。在默认情况下,Nginx仅处理HTTP和HTTPS请求,但不支持通过HTTP代理进行TCP连接,比如SSL/TLS隧道。这个...
ngx_cache_purge 是 nginx 模块,此模块可以清理 nginx 的 FastCGI、proxy、 SCGI 和 uWSGI 的缓存。配置指令(相同位置语法)fastcgi_cache_purgesyntax: fastcgi_cache_purge on|off|<method> [from all|<ip> [.....
ngx_devel_kit(通常缩写为 NDK)是一个针对Nginx的模块开发工具集,它为构建自定义Nginx模块提供了便利。在Nginx生态系统中,NDK是一个重要的扩展工具,允许开发者利用C语言直接操作Nginx的内部结构,以实现更高级...
ngx_lua_module是一款强大的扩展模块,专为Nginx服务器设计,允许在Nginx配置文件中直接嵌入Lua脚本,极大地增强了Nginx的功能和灵活性。这个"ngx_lua_module-windows-1.1.2.0"是该模块的一个Windows版本,适应于...
【Nginx 限制连接数 ngx_http_limit_conn_module 模块详解】 在互联网服务中,服务器经常面临流量异常、负载过大的情况,尤其在遭受大流量恶意攻击时,带宽的浪费、服务器压力的增大都会对业务造成严重影响。为了...
lua-upstream-nginx-module, Nginx C 模块将Lua向ngx_lua公开,用于 Nginx upstreams 电子邮件名称ngx_http_lua_upstream - Nginx MODULE,用于向 Nginx upstreams公开Lua到 ngx_lua目录NAME状态概要说明函数get_...
ngx_req_status用来展示nginx请求状态信息,类似于apache的status,nginx自带的模块只能显示连接数等等信息,我们并不能知道到底有哪些请求、以及各url域名所消耗的带宽是多少。ngx_req_status提供了这些功能. 1、按...
ngx_sqlite 是嵌入 sqlite 数据库的 nginx 模块。通过强大的nginx server,可以使用http协议访问sqlite数据库。环境- sqlite 3- nginx-1.6.3 安装```sh $ git clone https://github.com/rryqszq4/ngx_sqlite.git...
使用nginx作为http/https正向代理ipm包,包含ngx_http_proxy_connect_module 模块,附带了第三方图片...下载后执行:rpm -ivh nginx-1.12.2-1.el7_4.ngx.x86_64.rpm 打包教程:https://www.jianshu.com/p/cd1c04c31534
这个版本2.4.2的压缩包包含了ngx_cache_purge模块的所有源代码及相关文件,以便开发者在自己的Nginx环境中集成和使用。 Nginx是一款高性能、轻量级的Web服务器和反向代理服务器,广泛应用于互联网服务。其内置的...
ngx_devel_kit是Nginx的一个重要扩展模块,它为Nginx提供了一系列的开发工具,方便开发者在Nginx上构建自定义模块。这个0.2.19版本的压缩包“ngx_devel_kit-0.2.19.tar.gz”包含了用于编译和开发Nginx模块所需的源...
ngx_http_dav_ext_module.so centos7 nginx 1.18 可以作为模块加载
nginx1.20.2
NGX_STREAM_SSL_PREREAD_MODULE 模块调研 NGX_STREAM_SSL_PREREAD_MODULE 是一个基于流媒体(Stream)实现的 SSL/TLS 协议 ClientHello 消息提取模块,主要用于提取 SNI(Server Name Indicate)或者 ALPN...
ngx_lua_waf是一个基于Nginx的Web应用防火墙,其核心是利用了Nginx的ngx_lua模块,通过Lua脚本实现灵活且强大的安全防护功能。ngx_lua_waf项目名称中的“master”通常指的是该项目的主分支或最新版本。"nearly11h...
同时,理解ngx_queue_t的实现方式也有助于提升对Nginx源码的理解,对于那些希望定制Nginx或者进行性能优化的开发者来说尤其重要。 总的来说,这个资源提供了一个学习和实践Nginx核心数据结构ngx_queue_t的良好机会...
【Nginx流媒体服务器构建与Yamdi工具详解】 在现代互联网中,视频流服务已经成为不可或缺的一部分。Nginx,作为一个高性能的Web服务器和反向代理服务器,因其高效的并发处理能力和轻量级的特性,常被用于搭建流媒体...
ngx_realtime_request是nginx用来统计虚拟主机流量的模块, 首先和大家说下这个模块是基于域名的,将会记录这个域名的请求量、发送字节、返回http状态码的数量,特性如下: 1、基于域名记录 2、记录请求数据量 3、...
"nginx" 表明这个话题与 Nginx 服务器软件有关,而 "一致性哈希模块" 暗示我们讨论的是 Nginx 中用于处理一致性哈希功能的扩展模块。 **压缩包子文件列表:** 由于未提供具体的子文件列表,我们假设该压缩包包含了...