diff options
Diffstat (limited to 'src/nxt_var.c')
-rw-r--r-- | src/nxt_var.c | 196 |
1 files changed, 89 insertions, 107 deletions
diff --git a/src/nxt_var.c b/src/nxt_var.c index e113969f..729de788 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -50,14 +50,11 @@ struct nxt_var_query_s { 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_decl_get(nxt_str_t *name, nxt_array_t *fields, - uint32_t *index); -static nxt_var_field_t *nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, - uint32_t hash); +static nxt_var_ref_t *nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name); static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); -static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, - uint32_t index, void *ctx); +static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, uint32_t index, void *ctx); static u_char *nxt_var_next_part(u_char *start, u_char *end, nxt_str_t *part); @@ -80,7 +77,7 @@ static const nxt_lvlhsh_proto_t nxt_var_cache_proto nxt_aligned(64) = { static nxt_lvlhsh_t nxt_var_hash; static uint32_t nxt_var_count; -static nxt_var_handler_t *nxt_var_index; +static nxt_var_decl_t **nxt_vars; static nxt_int_t @@ -111,95 +108,70 @@ nxt_var_hash_find(nxt_str_t *name) } -static nxt_var_decl_t * -nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields, uint32_t *index) +static nxt_var_ref_t * +nxt_var_ref_get(nxt_tstr_state_t *state, nxt_str_t *name) { - u_char *p, *end; - int64_t hash; - uint16_t field; - nxt_str_t str; - nxt_var_decl_t *decl; - nxt_var_field_t *f; - - f = NULL; - field = 0; - decl = nxt_var_hash_find(name); + nxt_int_t ret; + nxt_uint_t i; + nxt_var_ref_t *ref; + nxt_var_decl_t *decl; - if (decl == NULL) { - p = name->start; - end = p + name->length; + ref = state->var_refs->elts; - while (p < end) { - if (*p++ == '_') { - break; - } - } + for (i = 0; i < state->var_refs->nelts; i++) { - if (p == end) { - return NULL; + if (nxt_strstr_eq(ref[i].name, name)) { + return &ref[i]; } + } - str.start = name->start; - str.length = p - 1 - name->start; + ref = nxt_array_add(state->var_refs); + if (nxt_slow_path(ref == NULL)) { + return NULL; + } - decl = nxt_var_hash_find(&str); + ref->index = state->var_refs->nelts - 1; - if (decl != NULL) { - str.start = p; - str.length = end - p; + ref->name = nxt_str_dup(state->pool, NULL, name); + if (nxt_slow_path(ref->name == NULL)) { + return NULL; + } - hash = decl->field_hash(fields->mem_pool, &str); - if (nxt_slow_path(hash == -1)) { - return NULL; - } + decl = nxt_var_hash_find(name); - f = nxt_var_field_add(fields, &str, (uint32_t) hash); - if (nxt_slow_path(f == NULL)) { - return NULL; - } + if (decl != NULL) { + ref->handler = decl->handler; + ref->cacheable = decl->cacheable; - field = f->index; - } + return ref; } - if (decl != NULL) { - if (decl->field_hash != NULL && f == NULL) { - return NULL; - } - - if (index != NULL) { - *index = (decl->index << 16) | field; - } + ret = nxt_http_unknown_var_ref(state, ref, name); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; } - return decl; + return ref; } -static nxt_var_field_t * -nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, uint32_t hash) +nxt_var_field_t * +nxt_var_field_new(nxt_mp_t *mp, nxt_str_t *name, uint32_t hash) { - nxt_uint_t i; + nxt_str_t *str; nxt_var_field_t *field; - field = fields->elts; - - for (i = 0; i < fields->nelts; i++) { - if (field[i].hash == hash - && nxt_strstr_eq(&field[i].name, name)) - { - return field; - } + field = nxt_mp_alloc(mp, sizeof(nxt_var_field_t)); + if (nxt_slow_path(field == NULL)) { + return NULL; } - field = nxt_array_add(fields); - if (nxt_slow_path(field == NULL)) { + str = nxt_str_dup(mp, &field->name, name); + if (nxt_slow_path(str == NULL)) { return NULL; } - field->name = *name; field->hash = hash; - field->index = fields->nelts - 1; return field; } @@ -230,13 +202,17 @@ nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) static nxt_str_t * -nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index, - void *ctx) +nxt_var_cache_value(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, uint32_t index, void *ctx) { nxt_int_t ret; nxt_str_t *value; + nxt_var_ref_t *ref; nxt_lvlhsh_query_t lhq; + ref = state->var_refs->elts; + ref = &ref[index]; + value = cache->spare; if (value == NULL) { @@ -248,6 +224,10 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index, cache->spare = value; } + if (!ref->cacheable) { + goto not_cached; + } + lhq.key_hash = nxt_murmur_hash2_uint32(&index); lhq.replace = 0; lhq.key.length = sizeof(uint32_t); @@ -261,16 +241,20 @@ nxt_var_cache_value(nxt_task_t *task, nxt_var_cache_t *cache, uint32_t index, return NULL; } - if (ret == NXT_OK) { - ret = nxt_var_index[index >> 16](task, value, ctx, index & 0xffff); - if (nxt_slow_path(ret != NXT_OK)) { - return NULL; - } + if (ret == NXT_DECLINED) { + return lhq.value; + } + +not_cached: - cache->spare = NULL; + ret = ref->handler(task, value, ctx, ref->data); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; } - return lhq.value; + cache->spare = NULL; + + return value; } @@ -303,12 +287,11 @@ nxt_int_t nxt_var_index_init(void) { nxt_uint_t i; - nxt_var_decl_t *decl; - nxt_var_handler_t *index; + nxt_var_decl_t *decl, **vars; nxt_lvlhsh_each_t lhe; - index = nxt_memalign(64, nxt_var_count * sizeof(nxt_var_handler_t)); - if (index == NULL) { + vars = nxt_memalign(64, nxt_var_count * sizeof(nxt_var_decl_t *)); + if (vars == NULL) { return NXT_ERROR; } @@ -316,27 +299,25 @@ nxt_var_index_init(void) for (i = 0; i < nxt_var_count; i++) { decl = nxt_lvlhsh_each(&nxt_var_hash, &lhe); - decl->index = i; - index[i] = decl->handler; + vars[i] = decl; } - nxt_var_index = index; + nxt_vars = vars; return NXT_OK; } nxt_var_t * -nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) +nxt_var_compile(nxt_tstr_state_t *state, nxt_str_t *str) { - u_char *p, *end, *next, *src; - size_t size; - uint32_t index; - nxt_var_t *var; - nxt_str_t part; - nxt_uint_t n; - nxt_var_sub_t *subs; - nxt_var_decl_t *decl; + u_char *p, *end, *next, *src; + size_t size; + nxt_var_t *var; + nxt_str_t part; + nxt_uint_t n; + nxt_var_sub_t *subs; + nxt_var_ref_t *ref; n = 0; @@ -356,7 +337,7 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) size = sizeof(nxt_var_t) + n * sizeof(nxt_var_sub_t) + str->length; - var = nxt_mp_get(mp, size); + var = nxt_mp_get(state->pool, size); if (nxt_slow_path(var == NULL)) { return NULL; } @@ -376,12 +357,12 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) next = nxt_var_next_part(p, end, &part); if (part.start != NULL) { - decl = nxt_var_decl_get(&part, fields, &index); - if (nxt_slow_path(decl == NULL)) { + ref = nxt_var_ref_get(state, &part); + if (nxt_slow_path(ref == NULL)) { return NULL; } - subs[n].index = index; + subs[n].index = ref->index; subs[n].length = next - p; subs[n].position = p - str->start; @@ -396,11 +377,11 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields) nxt_int_t -nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error) +nxt_var_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) { - u_char *p, *end, *next; - nxt_str_t part; - nxt_var_decl_t *decl; + u_char *p, *end, *next; + nxt_str_t part; + nxt_var_ref_t *ref; p = str->start; end = p + str->length; @@ -416,9 +397,9 @@ nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error) } if (part.start != NULL) { - decl = nxt_var_decl_get(&part, fields, NULL); + ref = nxt_var_ref_get(state, &part); - if (decl == NULL) { + if (ref == NULL) { nxt_sprintf(error, error + NXT_MAX_ERROR_STR, "Unknown variable \"%V\"%Z", &part); @@ -504,8 +485,9 @@ nxt_var_next_part(u_char *start, u_char *end, nxt_str_t *part) nxt_int_t -nxt_var_interpreter(nxt_task_t *task, nxt_var_cache_t *cache, nxt_var_t *var, - nxt_str_t *str, void *ctx, nxt_bool_t logging) +nxt_var_interpreter(nxt_task_t *task, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, nxt_var_t *var, nxt_str_t *str, void *ctx, + nxt_bool_t logging) { u_char *p, *src; size_t length, last, next; @@ -522,7 +504,7 @@ nxt_var_interpreter(nxt_task_t *task, nxt_var_cache_t *cache, nxt_var_t *var, length = var->length; for (i = 0; i < var->vars; i++) { - value = nxt_var_cache_value(task, cache, subs[i].index, ctx); + value = nxt_var_cache_value(task, state, cache, subs[i].index, ctx); if (nxt_slow_path(value == NULL)) { return NXT_ERROR; } |