change ngx_http_variable_value_node_t to more generic ngx_str_node_t

This commit is contained in:
Igor Sysoev 2010-06-23 15:31:33 +00:00
parent 2c72df5ed4
commit 0923d08148
5 changed files with 116 additions and 111 deletions

View File

@ -1638,6 +1638,89 @@ ngx_escape_html(u_char *dst, u_char *src, size_t size)
}
void
ngx_str_rbtree_insert_value(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
{
ngx_str_node_t *n, *t;
ngx_rbtree_node_t **p;
for ( ;; ) {
n = (ngx_str_node_t *) node;
t = (ngx_str_node_t *) temp;
if (node->key != temp->key) {
p = (node->key < temp->key) ? &temp->left : &temp->right;
} else if (n->str.len != t->str.len) {
p = (n->str.len < t->str.len) ? &temp->left : &temp->right;
} else {
p = (ngx_memcmp(n->str.data, t->str.data, n->str.len) < 0)
? &temp->left : &temp->right;
}
if (*p == sentinel) {
break;
}
temp = *p;
}
*p = node;
node->parent = temp;
node->left = sentinel;
node->right = sentinel;
ngx_rbt_red(node);
}
ngx_str_node_t *
ngx_str_rbtree_lookup(ngx_rbtree_t *rbtree, ngx_str_t *val, uint32_t hash)
{
ngx_int_t rc;
ngx_str_node_t *n;
ngx_rbtree_node_t *node, *sentinel;
node = rbtree->root;
sentinel = rbtree->sentinel;
while (node != sentinel) {
n = (ngx_str_node_t *) node;
if (hash != node->key) {
node = (hash < node->key) ? node->left : node->right;
continue;
}
if (val->len != n->str.len) {
node = (val->len < n->str.len) ? node->left : node->right;
continue;
}
rc = ngx_memcmp(val->data, n->str.data, val->len);
if (rc < 0) {
node = node->left;
continue;
}
if (rc > 0) {
node = node->right;
continue;
}
return n;
}
return NULL;
}
/* ngx_sort() is implemented as insertion sort because we need stable sort */
void

View File

@ -200,6 +200,17 @@ void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
typedef struct {
ngx_rbtree_node_t node;
ngx_str_t str;
} ngx_str_node_t;
void ngx_str_rbtree_insert_value(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
ngx_str_node_t *ngx_str_rbtree_lookup(ngx_rbtree_t *rbtree, ngx_str_t *name,
uint32_t hash);
void ngx_sort(void *base, size_t n, size_t size,
ngx_int_t (*cmp)(const void *, const void *));

View File

@ -28,6 +28,12 @@ typedef struct {
} ngx_http_geo_high_ranges_t;
typedef struct {
ngx_str_node_t sn;
ngx_http_variable_value_t *value;
} ngx_http_geo_variable_value_node_t;
typedef struct {
ngx_http_variable_value_t *value;
ngx_str_t *net;
@ -307,8 +313,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel,
ngx_http_variable_value_rbtree_insert);
ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel, ngx_str_rbtree_insert_value);
ctx.high = NULL;
ctx.tree = NULL;
@ -929,16 +934,17 @@ static ngx_http_variable_value_t *
ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_str_t *value)
{
uint32_t hash;
ngx_http_variable_value_t *val;
ngx_http_variable_value_node_t *vvn;
uint32_t hash;
ngx_http_variable_value_t *val;
ngx_http_geo_variable_value_node_t *gvvn;
hash = ngx_crc32_long(value->data, value->len);
val = ngx_http_variable_value_lookup(&ctx->rbtree, value, hash);
gvvn = (ngx_http_geo_variable_value_node_t *)
ngx_str_rbtree_lookup(&ctx->rbtree, value, hash);
if (val) {
return val;
if (gvvn) {
return gvvn->value;
}
val = ngx_palloc(ctx->pool, sizeof(ngx_http_variable_value_t));
@ -956,16 +962,18 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
val->no_cacheable = 0;
val->not_found = 0;
vvn = ngx_palloc(ctx->temp_pool, sizeof(ngx_http_variable_value_node_t));
if (vvn == NULL) {
gvvn = ngx_palloc(ctx->temp_pool,
sizeof(ngx_http_geo_variable_value_node_t));
if (gvvn == NULL) {
return NULL;
}
vvn->node.key = hash;
vvn->len = val->len;
vvn->value = val;
gvvn->sn.node.key = hash;
gvvn->sn.str.len = val->len;
gvvn->sn.str.data = val->data;
gvvn->value = val;
ngx_rbtree_insert(&ctx->rbtree, &vvn->node);
ngx_rbtree_insert(&ctx->rbtree, &gvvn->sn.node);
return val;
}

View File

@ -1973,87 +1973,3 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
return NGX_OK;
}
void
ngx_http_variable_value_rbtree_insert(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
{
ngx_rbtree_node_t **p;
ngx_http_variable_value_node_t *vvn, *vvt;
for ( ;; ) {
vvn = (ngx_http_variable_value_node_t *) node;
vvt = (ngx_http_variable_value_node_t *) temp;
if (node->key != temp->key) {
p = (node->key < temp->key) ? &temp->left : &temp->right;
} else if (vvn->len != vvt->len) {
p = (vvn->len < vvt->len) ? &temp->left : &temp->right;
} else {
p = (ngx_memcmp(vvn->value->data, vvt->value->data, vvn->len) < 0)
? &temp->left : &temp->right;
}
if (*p == sentinel) {
break;
}
temp = *p;
}
*p = node;
node->parent = temp;
node->left = sentinel;
node->right = sentinel;
ngx_rbt_red(node);
}
ngx_http_variable_value_t *
ngx_http_variable_value_lookup(ngx_rbtree_t *rbtree, ngx_str_t *val,
uint32_t hash)
{
ngx_int_t rc;
ngx_rbtree_node_t *node, *sentinel;
ngx_http_variable_value_node_t *vvn;
node = rbtree->root;
sentinel = rbtree->sentinel;
while (node != sentinel) {
vvn = (ngx_http_variable_value_node_t *) node;
if (hash != node->key) {
node = (hash < node->key) ? node->left : node->right;
continue;
}
if (val->len != vvn->len) {
node = (val->len < vvn->len) ? node->left : node->right;
continue;
}
rc = ngx_memcmp(val->data, vvn->value->data, val->len);
if (rc < 0) {
node = node->left;
continue;
}
if (rc > 0) {
node = node->right;
continue;
}
return vvn->value;
}
return NULL;
}

View File

@ -88,19 +88,6 @@ ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf);
ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf);
typedef struct {
ngx_rbtree_node_t node;
size_t len;
ngx_http_variable_value_t *value;
} ngx_http_variable_value_node_t;
void ngx_http_variable_value_rbtree_insert(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
ngx_http_variable_value_t *ngx_http_variable_value_lookup(ngx_rbtree_t *rbtree,
ngx_str_t *name, uint32_t hash);
extern ngx_http_variable_value_t ngx_http_variable_null_value;
extern ngx_http_variable_value_t ngx_http_variable_true_value;