【nginx源码学习与运用 七】基数树结构ngx_radix_tree_t

【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:  [email protected]
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;
}

运行结果

截图如下:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012819339/article/details/53581203