One Level Up
Top Level
src/core/ngx_radix_tree.c - nginx-1.7.10
Functions defined
Source code
- #include <ngx_config.h>
- #include <ngx_core.h>
- static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree);
- ngx_radix_tree_t *
- ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate)
- {
- uint32_t key, mask, inc;
- ngx_radix_tree_t *tree;
- tree = ngx_palloc(pool, sizeof(ngx_radix_tree_t));
- if (tree == NULL) {
- return NULL;
- }
- tree->pool = pool;
- tree->free = NULL;
- tree->start = NULL;
- tree->size = 0;
- tree->root = ngx_radix_alloc(tree);
- if (tree->root == NULL) {
- return NULL;
- }
- tree->root->right = NULL;
- tree->root->left = NULL;
- tree->root->parent = NULL;
- tree->root->value = NGX_RADIX_NO_VALUE;
- if (preallocate == 0) {
- return tree;
- }
-
- if (preallocate == -1) {
- switch (ngx_pagesize / sizeof(ngx_radix_node_t)) {
-
- case 128:
- preallocate = 6;
- break;
-
- case 256:
- preallocate = 7;
- break;
-
- default:
- preallocate = 8;
- }
- }
- mask = 0;
- inc = 0x80000000;
- while (preallocate--) {
- key = 0;
- mask >>= 1;
- mask |= 0x80000000;
- do {
- if (ngx_radix32tree_insert(tree, key, mask, NGX_RADIX_NO_VALUE)
- != NGX_OK)
- {
- return NULL;
- }
- key += inc;
- } while (key);
- inc >>= 1;
- }
- 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, *next;
- bit = 0x80000000;
- node = tree->root;
- next = tree->root;
- while (bit & mask) {
- if (key & bit) {
- next = node->right;
- } else {
- next = node->left;
- }
- if (next == NULL) {
- break;
- }
- bit >>= 1;
- node = next;
- }
- if (next) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- return NGX_BUSY;
- }
- node->value = value;
- return NGX_OK;
- }
- while (bit & mask) {
- next = ngx_radix_alloc(tree);
- if (next == NULL) {
- return NGX_ERROR;
- }
- next->right = NULL;
- next->left = NULL;
- next->parent = node;
- next->value = NGX_RADIX_NO_VALUE;
- if (key & bit) {
- node->right = next;
- } else {
- node->left = next;
- }
- bit >>= 1;
- node = next;
- }
- node->value = value;
- return NGX_OK;
- }
- ngx_int_t
- ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask)
- {
- uint32_t bit;
- ngx_radix_node_t *node;
- bit = 0x80000000;
- node = tree->root;
- while (node && (bit & mask)) {
- if (key & bit) {
- node = node->right;
- } else {
- node = node->left;
- }
- bit >>= 1;
- }
- if (node == NULL) {
- return NGX_ERROR;
- }
- if (node->right || node->left) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- node->value = NGX_RADIX_NO_VALUE;
- return NGX_OK;
- }
- return NGX_ERROR;
- }
- for ( ;; ) {
- if (node->parent->right == node) {
- node->parent->right = NULL;
- } else {
- node->parent->left = NULL;
- }
- node->right = tree->free;
- tree->free = node;
- node = node->parent;
- if (node->right || node->left) {
- break;
- }
- if (node->value != NGX_RADIX_NO_VALUE) {
- break;
- }
- if (node->parent == NULL) {
- break;
- }
- }
- return NGX_OK;
- }
- 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;
- value = NGX_RADIX_NO_VALUE;
- node = tree->root;
- while (node) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- value = node->value;
- }
- if (key & bit) {
- node = node->right;
- } else {
- node = node->left;
- }
- bit >>= 1;
- }
- return value;
- }
- #if (NGX_HAVE_INET6)
- ngx_int_t
- ngx_radix128tree_insert(ngx_radix_tree_t *tree, u_char *key, u_char *mask,
- uintptr_t value)
- {
- u_char bit;
- ngx_uint_t i;
- ngx_radix_node_t *node, *next;
- i = 0;
- bit = 0x80;
- node = tree->root;
- next = tree->root;
- while (bit & mask[i]) {
- if (key[i] & bit) {
- next = node->right;
- } else {
- next = node->left;
- }
- if (next == NULL) {
- break;
- }
- bit >>= 1;
- node = next;
- if (bit == 0) {
- if (++i == 16) {
- break;
- }
- bit = 0x80;
- }
- }
- if (next) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- return NGX_BUSY;
- }
- node->value = value;
- return NGX_OK;
- }
- while (bit & mask[i]) {
- next = ngx_radix_alloc(tree);
- if (next == NULL) {
- return NGX_ERROR;
- }
- next->right = NULL;
- next->left = NULL;
- next->parent = node;
- next->value = NGX_RADIX_NO_VALUE;
- if (key[i] & bit) {
- node->right = next;
- } else {
- node->left = next;
- }
- bit >>= 1;
- node = next;
- if (bit == 0) {
- if (++i == 16) {
- break;
- }
- bit = 0x80;
- }
- }
- node->value = value;
- return NGX_OK;
- }
- ngx_int_t
- ngx_radix128tree_delete(ngx_radix_tree_t *tree, u_char *key, u_char *mask)
- {
- u_char bit;
- ngx_uint_t i;
- ngx_radix_node_t *node;
- i = 0;
- bit = 0x80;
- node = tree->root;
- while (node && (bit & mask[i])) {
- if (key[i] & bit) {
- node = node->right;
- } else {
- node = node->left;
- }
- bit >>= 1;
- if (bit == 0) {
- if (++i == 16) {
- break;
- }
- bit = 0x80;
- }
- }
- if (node == NULL) {
- return NGX_ERROR;
- }
- if (node->right || node->left) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- node->value = NGX_RADIX_NO_VALUE;
- return NGX_OK;
- }
- return NGX_ERROR;
- }
- for ( ;; ) {
- if (node->parent->right == node) {
- node->parent->right = NULL;
- } else {
- node->parent->left = NULL;
- }
- node->right = tree->free;
- tree->free = node;
- node = node->parent;
- if (node->right || node->left) {
- break;
- }
- if (node->value != NGX_RADIX_NO_VALUE) {
- break;
- }
- if (node->parent == NULL) {
- break;
- }
- }
- return NGX_OK;
- }
- uintptr_t
- ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key)
- {
- u_char bit;
- uintptr_t value;
- ngx_uint_t i;
- ngx_radix_node_t *node;
- i = 0;
- bit = 0x80;
- value = NGX_RADIX_NO_VALUE;
- node = tree->root;
- while (node) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- value = node->value;
- }
- if (key[i] & bit) {
- node = node->right;
- } else {
- node = node->left;
- }
- bit >>= 1;
- if (bit == 0) {
- i++;
- bit = 0x80;
- }
- }
- return value;
- }
- #endif
- static ngx_radix_node_t *
- ngx_radix_alloc(ngx_radix_tree_t *tree)
- {
- ngx_radix_node_t *p;
- if (tree->free) {
- p = tree->free;
- tree->free = tree->free->right;
- return p;
- }
- if (tree->size < sizeof(ngx_radix_node_t)) {
- tree->start = ngx_pmemalign(tree->pool, ngx_pagesize, ngx_pagesize);
- if (tree->start == NULL) {
- return NULL;
- }
- tree->size = ngx_pagesize;
- }
- p = (ngx_radix_node_t *) tree->start;
- tree->start += sizeof(ngx_radix_node_t);
- tree->size -= sizeof(ngx_radix_node_t);
- return p;
- }
One Level Up
Top Level