mirror of
https://github.com/nginx/nginx.git
synced 2024-11-27 15:39:01 +08:00
add radix tree skip node
This commit is contained in:
parent
36de6230cc
commit
350d027491
@ -10,6 +10,8 @@
|
||||
|
||||
static ngx_int_t ngx_radix32tree_delete_node(ngx_radix_tree_t *tree,
|
||||
uint32_t key, uint32_t mask, ngx_radix_node_t **pnode, uint32_t bit);
|
||||
void ngx_radix32tree_compress_node(ngx_radix_tree_t *tree,
|
||||
ngx_radix_node_t *node);
|
||||
static void *ngx_radix_alloc(ngx_radix_tree_t *tree);
|
||||
|
||||
|
||||
@ -28,6 +30,7 @@ ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate)
|
||||
tree->free = NULL;
|
||||
tree->start = NULL;
|
||||
tree->size = 0;
|
||||
tree->count = 0;
|
||||
|
||||
tree->root = ngx_radix_alloc(tree);
|
||||
if (tree->root == NULL) {
|
||||
@ -205,6 +208,7 @@ ngx_radix32tree_delete_node(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
|
||||
} else {
|
||||
node->right = tree->free;
|
||||
tree->free = node;
|
||||
tree->count--;
|
||||
|
||||
*pnode = NULL;
|
||||
}
|
||||
@ -230,6 +234,7 @@ ngx_radix32tree_delete_node(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
|
||||
|
||||
node->right = tree->free;
|
||||
tree->free = node;
|
||||
tree->count--;
|
||||
|
||||
*pnode = NULL;
|
||||
|
||||
@ -237,33 +242,114 @@ ngx_radix32tree_delete_node(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_radix32tree_compress(ngx_radix_tree_t *tree)
|
||||
{
|
||||
if (tree->root) {
|
||||
ngx_radix32tree_compress_node(tree, tree->root);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_radix32tree_compress_node(ngx_radix_tree_t *tree, ngx_radix_node_t *node)
|
||||
{
|
||||
uintptr_t skip;
|
||||
ngx_radix_node_t *n;
|
||||
|
||||
if (node->right) {
|
||||
|
||||
skip = 0;
|
||||
|
||||
for (n = node->right;
|
||||
n->right && n->left == NULL && n->value == NGX_RADIX_NO_VALUE;
|
||||
n = node->right)
|
||||
{
|
||||
node->right = n->right;
|
||||
|
||||
n->right = tree->free;
|
||||
tree->free = n;
|
||||
tree->count--;
|
||||
|
||||
skip++;
|
||||
}
|
||||
|
||||
node->right->skip = skip;
|
||||
|
||||
ngx_radix32tree_compress_node(tree, node->right);
|
||||
}
|
||||
|
||||
if (node->left) {
|
||||
|
||||
skip = 0;
|
||||
|
||||
for (n = node->left;
|
||||
n->left && n->right == NULL && n->value == NGX_RADIX_NO_VALUE;
|
||||
n = node->left)
|
||||
{
|
||||
node->left = n->left;
|
||||
|
||||
n->right = tree->free;
|
||||
tree->free = n;
|
||||
tree->count--;
|
||||
|
||||
skip++;
|
||||
}
|
||||
|
||||
node->left->skip = skip;
|
||||
|
||||
ngx_radix32tree_compress_node(tree, node->left);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uintptr_t
|
||||
ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key)
|
||||
{
|
||||
uint32_t bit;
|
||||
uintptr_t value;
|
||||
uint32_t bit, test;
|
||||
uintptr_t value, skip;
|
||||
ngx_radix_node_t *node;
|
||||
|
||||
bit = 0x80000000;
|
||||
value = NGX_RADIX_NO_VALUE;
|
||||
node = tree->root;
|
||||
|
||||
while (node) {
|
||||
if (node == NULL) {
|
||||
return NGX_RADIX_NO_VALUE;
|
||||
}
|
||||
|
||||
bit = 0x80000000;
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
if (node->value != NGX_RADIX_NO_VALUE) {
|
||||
value = node->value;
|
||||
}
|
||||
|
||||
if (key & bit) {
|
||||
node = node->right;
|
||||
test = 0;
|
||||
|
||||
} else {
|
||||
node = node->left;
|
||||
test = bit >> 1;
|
||||
}
|
||||
|
||||
if (node == NULL) {
|
||||
return value;
|
||||
}
|
||||
|
||||
bit >>= 1;
|
||||
|
||||
for (skip = node->skip; skip; skip--) {
|
||||
|
||||
if ((key & bit) == test) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return value;
|
||||
bit >>= 1;
|
||||
test >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -275,6 +361,7 @@ ngx_radix_alloc(ngx_radix_tree_t *tree)
|
||||
if (tree->free) {
|
||||
p = (char *) tree->free;
|
||||
tree->free = tree->free->right;
|
||||
tree->count++;
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -290,6 +377,7 @@ ngx_radix_alloc(ngx_radix_tree_t *tree)
|
||||
p = tree->start;
|
||||
tree->start += sizeof(ngx_radix_node_t);
|
||||
tree->size -= sizeof(ngx_radix_node_t);
|
||||
tree->count++;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ 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_uint_t skip;
|
||||
uintptr_t skip;
|
||||
uintptr_t value;
|
||||
};
|
||||
|
||||
@ -30,6 +30,7 @@ typedef struct {
|
||||
ngx_radix_node_t *free;
|
||||
char *start;
|
||||
size_t size;
|
||||
ngx_uint_t count;
|
||||
} ngx_radix_tree_t;
|
||||
|
||||
|
||||
@ -39,6 +40,7 @@ ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree,
|
||||
uint32_t key, uint32_t mask, uintptr_t value);
|
||||
ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree,
|
||||
uint32_t key, uint32_t mask);
|
||||
void ngx_radix32tree_compress(ngx_radix_tree_t *tree);
|
||||
uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key);
|
||||
|
||||
|
||||
|
@ -171,7 +171,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
char *rv;
|
||||
size_t len;
|
||||
ngx_str_t *value, name;
|
||||
ngx_uint_t i;
|
||||
ngx_uint_t i, count;
|
||||
ngx_conf_t save;
|
||||
ngx_pool_t *pool;
|
||||
ngx_array_t *a;
|
||||
@ -268,9 +268,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) {
|
||||
return rv;
|
||||
}
|
||||
if (ngx_radix32tree_find(ctx.tree, 0) == NGX_RADIX_NO_VALUE) {
|
||||
|
||||
if (ngx_radix32tree_insert(ctx.tree, 0, 0,
|
||||
(uintptr_t) &ngx_http_variable_null_value)
|
||||
@ -280,6 +278,15 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
count = ctx.tree->count;
|
||||
|
||||
ngx_radix32tree_compress(ctx.tree);
|
||||
|
||||
ngx_log_error(NGX_LOG_NOTICE, cf->log, 0,
|
||||
"\"%V\" geo tree has been compressed as %ui/%ui",
|
||||
&name, ctx.tree->count, count);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user