ngx_radix_tree_t基数树
基数树特点
基数树要求存储的每个节点都必须以32位整型作为区别任意两个节点的唯一标识。
i.e.
有深度为3的基数树,包含四个节点:0x20000000、0x40000000、0x80000000、0xA0000000,其实基数树是按二进制来建树的。
由上图可知,基数树的最大深度为32。然而,有些时候数据可能只是在前几层,所以nginx提供了一个掩码方式。32位的掩码,从左至右,第一位起,连续1所在位的个数即树的层数。
基数树节点结构体
typedef struct ngx_radix_node_s ngx_radix_node_t;
struct ngx_radix_node_s {
//指向右子树,如果没有右子树,则值为null
ngx_radix_node_t *right;
//指向左子树,如果没有右子树,则值为null
ngx_radix_node_t *left;
//指向父节点,如果没有父节点,则值为null
ngx_radix_node_t *parent;
/* value存储的是用户定义的数据结构,如果没有,value=NGX_RADIX_NO_VALUE */
uintptr_t value;
};
基数树容器结构体
typedef struct {
//指向根节点
ngx_radix_node_t *root;
//内存池,它负责给基数树的节点分配内存
ngx_pool_t *pool;
/* 管理已经分配但暂时未使用(不在树中)的节点,free实际上是所有不在树中节点的单链表 */
ngx_radix_node_t *free;
//已分配内存中还未使内存的首地址
char *start;
//已分配内存中还未使用的内存大小
size_t size;
}ngx_radix_tree_t;
pool对象用来分配内存。每当删除一个节点时,基数树不会真的释放这个内存,而是将它添加到free单链表中。下次需要申请新的节点时,就可来查找这个表中是否有可以用的节点。
基数树提供的函数
函数名 | 参数含义 | 执行意义 |
---|---|---|
ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool,ngx_int_t preallocate) | pool是内存池指针;preallocate是预分配的基数树节点数,如果为-1,将会根据系统中一个页面的大小来预分配基数树的节点 | 创建ngx_radix_tree_t基数树 |
ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree,uint32_t key,uint32_t mask,uintptr_t value) | tree是基数树指针;key是带插入节点的关键字;mask是关键字掩码(决定了树的深度);value是关键字对应数据结构的指针 | 插入节点。成功返回NGX_OK;空间不足返回NGX_ERROR;掩码设置错误返回NGX_BUSY |
ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree,uint32_t key,uint32_t mask) | 同上,mask确定关键字的有效位数 | 删除成功返回NGX_OK,否则返回NGX_ERROR |
ngx_int_t ngx_radix32tree_find(ngx_radix_tree_t *tree,uint32_t key) | 同上 | 查找成功返回uintptr_t数据结构的地址,否则返回NGX_RADIX_NO_VALUE |