Var: optimization to get rid of nxt_var_cache_find().
No functional changes.
This commit is contained in:
227
src/nxt_var.c
227
src/nxt_var.c
@@ -26,19 +26,12 @@ typedef struct {
|
|||||||
} nxt_var_sub_t;
|
} nxt_var_sub_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
nxt_var_t *var;
|
|
||||||
nxt_str_t *value;
|
|
||||||
} nxt_var_value_t;
|
|
||||||
|
|
||||||
|
|
||||||
struct nxt_var_query_s {
|
struct nxt_var_query_s {
|
||||||
nxt_array_t values; /* of nxt_var_value_t */
|
nxt_mp_t *pool;
|
||||||
nxt_array_t parts; /* of nxt_str_t * */
|
|
||||||
|
|
||||||
nxt_lvlhsh_t cache;
|
nxt_lvlhsh_t cache;
|
||||||
|
|
||||||
nxt_str_t *spare;
|
nxt_str_t *spare;
|
||||||
|
|
||||||
nxt_uint_t waiting;
|
nxt_uint_t waiting;
|
||||||
nxt_uint_t failed; /* 1 bit */
|
nxt_uint_t failed; /* 1 bit */
|
||||||
|
|
||||||
@@ -60,15 +53,12 @@ static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
|
|||||||
static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name);
|
static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name);
|
||||||
|
|
||||||
static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data);
|
static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data);
|
||||||
static nxt_str_t *nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index);
|
static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query,
|
||||||
static nxt_int_t nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index,
|
uint32_t index);
|
||||||
nxt_str_t *value, nxt_mp_t *mp);
|
|
||||||
|
|
||||||
static u_char *nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part,
|
static u_char *nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part,
|
||||||
nxt_bool_t *is_var);
|
nxt_bool_t *is_var);
|
||||||
|
|
||||||
static void nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query);
|
|
||||||
|
|
||||||
|
|
||||||
static const nxt_lvlhsh_proto_t nxt_var_hash_proto nxt_aligned(64) = {
|
static const nxt_lvlhsh_proto_t nxt_var_hash_proto nxt_aligned(64) = {
|
||||||
NXT_LVLHSH_DEFAULT,
|
NXT_LVLHSH_DEFAULT,
|
||||||
@@ -127,28 +117,22 @@ nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data)
|
|||||||
|
|
||||||
|
|
||||||
static nxt_str_t *
|
static nxt_str_t *
|
||||||
nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index)
|
nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, uint32_t index)
|
||||||
{
|
{
|
||||||
|
nxt_int_t ret;
|
||||||
|
nxt_str_t *value;
|
||||||
nxt_lvlhsh_query_t lhq;
|
nxt_lvlhsh_query_t lhq;
|
||||||
|
|
||||||
lhq.key_hash = nxt_murmur_hash2_uint32(&index);
|
value = query->spare;
|
||||||
lhq.key.length = sizeof(uint32_t);
|
|
||||||
lhq.key.start = (u_char *) &index;
|
|
||||||
lhq.proto = &nxt_var_cache_proto;
|
|
||||||
|
|
||||||
if (nxt_lvlhsh_find(lh, &lhq) != NXT_OK) {
|
if (value == NULL) {
|
||||||
|
value = nxt_mp_zget(query->pool, sizeof(nxt_str_t));
|
||||||
|
if (nxt_slow_path(value == NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lhq.value;
|
query->spare = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nxt_int_t
|
|
||||||
nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, nxt_str_t *value,
|
|
||||||
nxt_mp_t *mp)
|
|
||||||
{
|
|
||||||
nxt_lvlhsh_query_t lhq;
|
|
||||||
|
|
||||||
lhq.key_hash = nxt_murmur_hash2_uint32(&index);
|
lhq.key_hash = nxt_murmur_hash2_uint32(&index);
|
||||||
lhq.replace = 0;
|
lhq.replace = 0;
|
||||||
@@ -156,9 +140,23 @@ nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, nxt_str_t *value,
|
|||||||
lhq.key.start = (u_char *) &index;
|
lhq.key.start = (u_char *) &index;
|
||||||
lhq.value = value;
|
lhq.value = value;
|
||||||
lhq.proto = &nxt_var_cache_proto;
|
lhq.proto = &nxt_var_cache_proto;
|
||||||
lhq.pool = mp;
|
lhq.pool = query->pool;
|
||||||
|
|
||||||
return nxt_lvlhsh_insert(lh, &lhq);
|
ret = nxt_lvlhsh_insert(&query->cache, &lhq);
|
||||||
|
if (nxt_slow_path(ret == NXT_ERROR)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == NXT_OK) {
|
||||||
|
ret = nxt_var_index[index](task, value, query->ctx);
|
||||||
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
query->spare = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lhq.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -432,14 +430,9 @@ nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_mp_t *mp)
|
|||||||
if (nxt_slow_path(query == NULL)) {
|
if (nxt_slow_path(query == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_array_init(&query->values, mp, sizeof(nxt_var_value_t));
|
|
||||||
nxt_array_init(&query->parts, mp, sizeof(nxt_str_t *));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
nxt_array_reset(&query->values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query->pool = mp;
|
||||||
query->ctx = ctx;
|
query->ctx = ctx;
|
||||||
|
|
||||||
*query_p = query;
|
*query_p = query;
|
||||||
@@ -452,13 +445,12 @@ void
|
|||||||
nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var,
|
nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var,
|
||||||
nxt_str_t *str)
|
nxt_str_t *str)
|
||||||
{
|
{
|
||||||
uint32_t index;
|
u_char *p, *src;
|
||||||
nxt_mp_t *mp;
|
size_t length, last, next;
|
||||||
nxt_str_t *value;
|
nxt_str_t *value, **part;
|
||||||
nxt_int_t ret;
|
|
||||||
nxt_uint_t i;
|
nxt_uint_t i;
|
||||||
|
nxt_array_t parts;
|
||||||
nxt_var_sub_t *subs;
|
nxt_var_sub_t *subs;
|
||||||
nxt_var_value_t *val;
|
|
||||||
|
|
||||||
if (nxt_var_is_const(var)) {
|
if (nxt_var_is_const(var)) {
|
||||||
nxt_var_raw(var, str);
|
nxt_var_raw(var, str);
|
||||||
@@ -469,48 +461,63 @@ nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp = query->values.mem_pool;
|
nxt_memzero(&parts, sizeof(nxt_array_t));
|
||||||
|
nxt_array_init(&parts, query->pool, sizeof(nxt_str_t *));
|
||||||
|
|
||||||
subs = nxt_var_subs(var);
|
subs = nxt_var_subs(var);
|
||||||
value = query->spare;
|
|
||||||
|
length = var->length;
|
||||||
|
|
||||||
for (i = 0; i < var->vars; i++) {
|
for (i = 0; i < var->vars; i++) {
|
||||||
|
value = nxt_var_cache_value(task, query, subs[i].index);
|
||||||
if (value == NULL) {
|
|
||||||
value = nxt_mp_zget(mp, sizeof(nxt_str_t));
|
|
||||||
if (nxt_slow_path(value == NULL)) {
|
if (nxt_slow_path(value == NULL)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
index = subs[i].index;
|
part = nxt_array_add(&parts);
|
||||||
|
if (nxt_slow_path(part == NULL)) {
|
||||||
ret = nxt_var_cache_add(&query->cache, index, value, mp);
|
|
||||||
|
|
||||||
if (ret != NXT_OK) {
|
|
||||||
if (nxt_slow_path(ret == NXT_ERROR)) {
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue; /* NXT_DECLINED */
|
*part = value;
|
||||||
|
|
||||||
|
length += value->length - subs[i].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nxt_var_index[index](task, value, query->ctx);
|
p = nxt_mp_nget(query->pool, length + var->strz);
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(p == NULL)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = NULL;
|
str->length = length;
|
||||||
|
str->start = p;
|
||||||
|
|
||||||
|
part = parts.elts;
|
||||||
|
src = nxt_var_raw_start(var);
|
||||||
|
|
||||||
|
last = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < var->vars; i++) {
|
||||||
|
next = subs[i].position;
|
||||||
|
|
||||||
|
if (next != last) {
|
||||||
|
p = nxt_cpymem(p, &src[last], next - last);
|
||||||
}
|
}
|
||||||
|
|
||||||
query->spare = value;
|
p = nxt_cpymem(p, part[i]->start, part[i]->length);
|
||||||
|
|
||||||
val = nxt_array_add(&query->values);
|
last = next + subs[i].length;
|
||||||
if (nxt_slow_path(val == NULL)) {
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val->var = var;
|
if (last != var->length) {
|
||||||
val->value = str;
|
p = nxt_cpymem(p, &src[last], var->length - last);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var->strz) {
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, str);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -529,7 +536,9 @@ nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data,
|
|||||||
query->error = error;
|
query->error = error;
|
||||||
|
|
||||||
if (query->waiting == 0) {
|
if (query->waiting == 0) {
|
||||||
nxt_var_query_finish(task, query);
|
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
|
||||||
|
query->failed ? query->error : query->ready,
|
||||||
|
task, query->ctx, query->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,94 +550,8 @@ nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query,
|
|||||||
query->failed |= failed;
|
query->failed |= failed;
|
||||||
|
|
||||||
if (--query->waiting == 0) {
|
if (--query->waiting == 0) {
|
||||||
nxt_var_query_finish(task, query);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query)
|
|
||||||
{
|
|
||||||
u_char *p, *src;
|
|
||||||
size_t length, last, next;
|
|
||||||
nxt_str_t *str, **part;
|
|
||||||
nxt_var_t *var;
|
|
||||||
nxt_uint_t i, j;
|
|
||||||
nxt_var_sub_t *subs;
|
|
||||||
nxt_var_value_t *val;
|
|
||||||
|
|
||||||
if (query->failed) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = query->values.elts;
|
|
||||||
|
|
||||||
for (i = 0; i < query->values.nelts; i++) {
|
|
||||||
var = val[i].var;
|
|
||||||
|
|
||||||
subs = nxt_var_subs(var);
|
|
||||||
length = var->length;
|
|
||||||
|
|
||||||
for (j = 0; j < var->vars; j++) {
|
|
||||||
str = nxt_var_cache_find(&query->cache, subs[j].index);
|
|
||||||
|
|
||||||
nxt_assert(str != NULL);
|
|
||||||
|
|
||||||
part = nxt_array_add(&query->parts);
|
|
||||||
|
|
||||||
if (nxt_slow_path(part == NULL)) {
|
|
||||||
query->failed = 1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
*part = str;
|
|
||||||
|
|
||||||
length += str->length - subs[j].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = nxt_mp_nget(query->values.mem_pool, length + var->strz);
|
|
||||||
if (nxt_slow_path(p == NULL)) {
|
|
||||||
query->failed = 1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
val[i].value->length = length;
|
|
||||||
val[i].value->start = p;
|
|
||||||
|
|
||||||
part = query->parts.elts;
|
|
||||||
src = nxt_var_raw_start(var);
|
|
||||||
|
|
||||||
last = 0;
|
|
||||||
|
|
||||||
for (j = 0; j < var->vars; j++) {
|
|
||||||
next = subs[j].position;
|
|
||||||
|
|
||||||
if (next != last) {
|
|
||||||
p = nxt_cpymem(p, &src[last], next - last);
|
|
||||||
}
|
|
||||||
|
|
||||||
p = nxt_cpymem(p, part[j]->start, part[j]->length);
|
|
||||||
|
|
||||||
last = next + subs[j].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last != var->length) {
|
|
||||||
p = nxt_cpymem(p, &src[last], var->length - last);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (var->strz) {
|
|
||||||
*p = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
nxt_array_reset(&query->parts);
|
|
||||||
|
|
||||||
nxt_debug(task, "var: \"%*s\" -> \"%V\"", var->length, src,
|
|
||||||
val[i].value);
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
|
|
||||||
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
|
nxt_work_queue_add(&task->thread->engine->fast_work_queue,
|
||||||
query->failed ? query->error : query->ready,
|
query->failed ? query->error : query->ready,
|
||||||
task, query->ctx, query->data);
|
task, query->ctx, query->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user