【nginx源码学习与运用】系列博客中的示例代码在csdn的代码托管服务器CODE上,地址https://code.csdn.net/u012819339/nginx_study ,你可以将其自由的下载到本地,或者通过Git来实时获取更新
nginx提供了基数树结构,该结构比较简单,所以本篇博客也会比较简单。
相关结构
struct ngx_radix_node_s {
ngx_radix_node_t *right; //指向右子树
ngx_radix_node_t *left; //指向左字数
ngx_radix_node_t *parent; //指向父节点
uintptr_t value; //存储的是指针的值,指向用户定义的数据结构。如果这个节点还未使用,value的值将是NGX_RADIX_NO_VALUE
};
typedef struct {
ngx_radix_node_t *root; //指向根节点
ngx_pool_t *pool; //提供内存的内存池
ngx_radix_node_t *free; //管理已经分配但暂时未使用(不在树中)的节点,free实际上是所有不在树中节点的单链表
char *start; //已分配内存中还未使用的内存首地址
size_t size; //已分配内存中还未使用的内存大小
} ngx_radix_tree_t;
结构图
3层基数树示意图:
操作方法
基数树提供了基本的插入、删除、查找方法
函数 | 解释 |
---|---|
ngx_radix_tree_create | 创建基数树,失败返回NULL指针,preallocate是预分配的基数树节点数,该值为-1表示根据当前操作系统中的一个页面大小来预分配基数树节点 |
ngx_radix32tree_insert | 向基数树中插入1个节点,成功返回NGX_OK。key是插入节点的关键字,mask为关键字掩码(决定key关键字有效位数及树的深度),value是这个关键字对应的数据结构的指针 |
ngx_radix32tree_delete | 删除一个节点,key是待删除节点的关键字,mask为关键字掩码。成功返回NGX_OK |
ngx_radix32tree_find | 查询一个节点,对于返回uintptr_t类型的指针地址,可以将其强制转换成自定义的数据结构指针使用,失败则返回NGX_RADIX_NO_VALUE |
示例代码
arvik将nginx中的部分基础结构代码提出来了,好作为新手学习练习使用。见 https://code.csdn.net/u012819339/nginx_study
main.c
/*
blog: http://blog.csdn.net/u012819339
email: 1216601195@qq.com
author: arvik
*/
#include <stdio.h>
#include <string.h>
#include "ak_core.h"
#include "pt.h"
int main()
{
ngx_pool_t *p;
p = ngx_create_pool(NGX_DEFAULT_POOL_SIZE); //16KB
if(p == NULL)
return -1;
ngx_radix_tree_t *radixTree = ngx_radix_tree_create(p, -1); //传入-1是想让ngx_pool_t只使用一个页面来尽可能的分配基数树节点
ngx_uint_t tv1 = 0x20000000;
ngx_uint_t tv2 = 0x40000000;
ngx_uint_t tv3 = 0x60000000;
ngx_uint_t tv4 = 0x80000000;
//将上述节点添加至radixTree中,掩码0xe0000000
int rc = NGX_OK;
rc |= ngx_radix32tree_insert(radixTree, 0x20000000, 0xe0000000, (uintptr_t)&tv1);
rc |= ngx_radix32tree_insert(radixTree, 0x40000000, 0xe0000000, (uintptr_t)&tv2);
rc |= ngx_radix32tree_insert(radixTree, 0x60000000, 0xe0000000, (uintptr_t)&tv3);
rc |= ngx_radix32tree_insert(radixTree, 0x80000000, 0xe0000000, (uintptr_t)&tv4);
//查找节点
ngx_uint_t *ptv = (ngx_uint_t *)ngx_radix32tree_find(radixTree, 0x80000000);
if(ptv == NGX_RADIX_NO_VALUE)
{
PT_Warn("not found!\n");
}
else
PT_Info("the node address:%x val:%x\n", ptv, *ptv);
ngx_destroy_pool(p);
return 0;
}
运行结果
截图如下: