2004-05-25 23:28:46 +08:00
|
|
|
|
|
|
|
#include <ngx_config.h>
|
|
|
|
#include <ngx_core.h>
|
|
|
|
|
|
|
|
|
|
|
|
/* STUB: page size */
|
|
|
|
#define NGX_RADIX_TREE_POOL_SIZE 4096
|
|
|
|
|
|
|
|
|
|
|
|
static void *ngx_radix_alloc(ngx_radix_tree_t *tree, size_t size);
|
|
|
|
|
|
|
|
|
|
|
|
ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool)
|
|
|
|
{
|
|
|
|
ngx_radix_tree_t *tree;
|
|
|
|
|
|
|
|
if (!(tree = ngx_palloc(pool, sizeof(ngx_radix_tree_t)))) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tree->root = NULL;
|
|
|
|
tree->pool = pool;
|
|
|
|
tree->free = NULL;
|
2004-05-26 23:30:12 +08:00
|
|
|
tree->start = NULL;
|
2004-05-25 23:28:46 +08:00
|
|
|
tree->size = 0;
|
|
|
|
|
|
|
|
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, *new;
|
|
|
|
|
|
|
|
bit = 0x80000000;
|
|
|
|
node = tree->root;
|
|
|
|
|
|
|
|
while (node && (bit & mask)) {
|
|
|
|
if (key & bit) {
|
|
|
|
node = node->right;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
node = node->left;
|
|
|
|
}
|
|
|
|
|
|
|
|
bit >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node) {
|
|
|
|
if (node->value) {
|
|
|
|
return NGX_BUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
node->value = value;
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (bit & mask) {
|
|
|
|
if (!(new = ngx_radix_alloc(tree, sizeof(ngx_radix_node_t)))) {
|
|
|
|
return NGX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
new->value = value;
|
2004-05-26 23:30:12 +08:00
|
|
|
new->right = NULL;
|
|
|
|
new->left = NULL;
|
2004-05-25 23:28:46 +08:00
|
|
|
|
|
|
|
if (key & bit) {
|
|
|
|
node->right = new;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
node->left = new;
|
|
|
|
}
|
|
|
|
|
|
|
|
bit >>= 1;
|
|
|
|
new = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask)
|
|
|
|
{
|
|
|
|
uint32_t bit;
|
2004-05-26 23:30:12 +08:00
|
|
|
ngx_radix_node_t *node, **prev;
|
2004-05-25 23:28:46 +08:00
|
|
|
|
|
|
|
bit = 0x80000000;
|
|
|
|
node = tree->root;
|
2004-05-26 23:30:12 +08:00
|
|
|
prev = NULL;
|
2004-05-25 23:28:46 +08:00
|
|
|
|
|
|
|
while (node && (bit & mask)) {
|
|
|
|
if (key & bit) {
|
2004-05-26 23:30:12 +08:00
|
|
|
prev = &node->right;;
|
2004-05-25 23:28:46 +08:00
|
|
|
node = node->right;
|
|
|
|
|
|
|
|
} else {
|
2004-05-26 23:30:12 +08:00
|
|
|
prev = &node->left;;
|
2004-05-25 23:28:46 +08:00
|
|
|
node = node->left;
|
|
|
|
}
|
|
|
|
|
|
|
|
bit >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (node) {
|
2004-05-26 23:30:12 +08:00
|
|
|
|
|
|
|
/* the leaf nodes are moved to the free list only */
|
|
|
|
|
|
|
|
if (node->right == NULL && node->left == NULL) {
|
|
|
|
*prev = NULL;
|
|
|
|
node->right = tree->free;
|
|
|
|
tree->free = node;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
node->value = (uintptr_t) 0;
|
|
|
|
}
|
2004-05-25 23:28:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2004-05-26 23:30:12 +08:00
|
|
|
value = (uintptr_t) 0;
|
2004-05-25 23:28:46 +08:00
|
|
|
node = tree->root;
|
|
|
|
|
|
|
|
while (node) {
|
|
|
|
if (node->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, size_t size)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
2004-05-26 23:30:12 +08:00
|
|
|
if (tree->free) {
|
|
|
|
p = (char *) tree->free;
|
|
|
|
tree->free = tree->free->right;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2004-05-25 23:28:46 +08:00
|
|
|
if (tree->size < size) {
|
2004-05-26 23:30:12 +08:00
|
|
|
if (!(tree->start = ngx_palloc(tree->pool, NGX_RADIX_TREE_POOL_SIZE))) {
|
2004-05-25 23:28:46 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tree->size = NGX_RADIX_TREE_POOL_SIZE;
|
|
|
|
}
|
|
|
|
|
2004-05-26 23:30:12 +08:00
|
|
|
p = tree->start;
|
|
|
|
tree->start += size;
|
2004-05-25 23:28:46 +08:00
|
|
|
tree->size -= size;
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|