Deleted
Added
nxt_var.c (2128:1ed9f036a2df) | nxt_var.c (2146:362258b173b3) |
---|---|
1 2/* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6#include <nxt_main.h> 7 8 --- 12 unchanged lines hidden (view full) --- 21 22typedef struct { 23 uint32_t index; 24 uint32_t length; 25 uint32_t position; 26} nxt_var_sub_t; 27 28 | 1 2/* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6#include <nxt_main.h> 7 8 --- 12 unchanged lines hidden (view full) --- 21 22typedef struct { 23 uint32_t index; 24 uint32_t length; 25 uint32_t position; 26} nxt_var_sub_t; 27 28 |
29typedef struct { 30 nxt_var_t *var; 31 nxt_str_t *value; 32} nxt_var_value_t; 33 34 | |
35struct nxt_var_query_s { | 29struct nxt_var_query_s { |
36 nxt_array_t values; /* of nxt_var_value_t */ 37 nxt_array_t parts; /* of nxt_str_t * */ | 30 nxt_mp_t *pool; |
38 39 nxt_lvlhsh_t cache; | 31 32 nxt_lvlhsh_t cache; |
40 | |
41 nxt_str_t *spare; | 33 nxt_str_t *spare; |
34 |
|
42 nxt_uint_t waiting; 43 nxt_uint_t failed; /* 1 bit */ 44 45 void *ctx; 46 void *data; 47 48 nxt_work_handler_t ready; 49 nxt_work_handler_t error; --- 5 unchanged lines hidden (view full) --- 55#define nxt_var_raw_start(var) \ 56 ((var)->data + (var)->vars * sizeof(nxt_var_sub_t)) 57 58 59static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data); 60static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name); 61 62static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); | 35 nxt_uint_t waiting; 36 nxt_uint_t failed; /* 1 bit */ 37 38 void *ctx; 39 void *data; 40 41 nxt_work_handler_t ready; 42 nxt_work_handler_t error; --- 5 unchanged lines hidden (view full) --- 48#define nxt_var_raw_start(var) \ 49 ((var)->data + (var)->vars * sizeof(nxt_var_sub_t)) 50 51 52static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data); 53static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name); 54 55static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); |
63static nxt_str_t *nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index); 64static nxt_int_t nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, 65 nxt_str_t *value, nxt_mp_t *mp); | 56static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, 57 uint32_t index); |
66 67static u_char *nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part, 68 nxt_bool_t *is_var); 69 | 58 59static u_char *nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part, 60 nxt_bool_t *is_var); 61 |
70static void nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query); | |
71 | 62 |
72 | |
73static const nxt_lvlhsh_proto_t nxt_var_hash_proto nxt_aligned(64) = { 74 NXT_LVLHSH_DEFAULT, 75 nxt_var_hash_test, 76 nxt_lvlhsh_alloc, 77 nxt_lvlhsh_free, 78}; 79 80static const nxt_lvlhsh_proto_t nxt_var_cache_proto nxt_aligned(64) = { --- 41 unchanged lines hidden (view full) --- 122static nxt_int_t 123nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) 124{ 125 return NXT_OK; 126} 127 128 129static nxt_str_t * | 63static const nxt_lvlhsh_proto_t nxt_var_hash_proto nxt_aligned(64) = { 64 NXT_LVLHSH_DEFAULT, 65 nxt_var_hash_test, 66 nxt_lvlhsh_alloc, 67 nxt_lvlhsh_free, 68}; 69 70static const nxt_lvlhsh_proto_t nxt_var_cache_proto nxt_aligned(64) = { --- 41 unchanged lines hidden (view full) --- 112static nxt_int_t 113nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) 114{ 115 return NXT_OK; 116} 117 118 119static nxt_str_t * |
130nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index) | 120nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, uint32_t index) |
131{ | 121{ |
122 nxt_int_t ret; 123 nxt_str_t *value; |
|
132 nxt_lvlhsh_query_t lhq; 133 | 124 nxt_lvlhsh_query_t lhq; 125 |
134 lhq.key_hash = nxt_murmur_hash2_uint32(&index); 135 lhq.key.length = sizeof(uint32_t); 136 lhq.key.start = (u_char *) &index; 137 lhq.proto = &nxt_var_cache_proto; | 126 value = query->spare; |
138 | 127 |
139 if (nxt_lvlhsh_find(lh, &lhq) != NXT_OK) { 140 return NULL; | 128 if (value == NULL) { 129 value = nxt_mp_zget(query->pool, sizeof(nxt_str_t)); 130 if (nxt_slow_path(value == NULL)) { 131 return NULL; 132 } 133 134 query->spare = value; |
141 } 142 | 135 } 136 |
143 return lhq.value; 144} 145 146 147static nxt_int_t 148nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, nxt_str_t *value, 149 nxt_mp_t *mp) 150{ 151 nxt_lvlhsh_query_t lhq; 152 | |
153 lhq.key_hash = nxt_murmur_hash2_uint32(&index); 154 lhq.replace = 0; 155 lhq.key.length = sizeof(uint32_t); 156 lhq.key.start = (u_char *) &index; 157 lhq.value = value; 158 lhq.proto = &nxt_var_cache_proto; | 137 lhq.key_hash = nxt_murmur_hash2_uint32(&index); 138 lhq.replace = 0; 139 lhq.key.length = sizeof(uint32_t); 140 lhq.key.start = (u_char *) &index; 141 lhq.value = value; 142 lhq.proto = &nxt_var_cache_proto; |
159 lhq.pool = mp; | 143 lhq.pool = query->pool; |
160 | 144 |
161 return nxt_lvlhsh_insert(lh, &lhq); | 145 ret = nxt_lvlhsh_insert(&query->cache, &lhq); 146 if (nxt_slow_path(ret == NXT_ERROR)) { 147 return NULL; 148 } 149 150 if (ret == NXT_OK) { 151 ret = nxt_var_index[index](task, value, query->ctx); 152 if (nxt_slow_path(ret != NXT_OK)) { 153 return NULL; 154 } 155 156 query->spare = NULL; 157 } 158 159 return lhq.value; |
162} 163 164 165nxt_int_t 166nxt_var_register(nxt_var_decl_t *decl, size_t n) 167{ 168 nxt_uint_t i; 169 nxt_lvlhsh_query_t lhq; --- 257 unchanged lines hidden (view full) --- 427 428 query = *query_p; 429 430 if (*query_p == NULL) { 431 query = nxt_mp_zget(mp, sizeof(nxt_var_query_t)); 432 if (nxt_slow_path(query == NULL)) { 433 return NXT_ERROR; 434 } | 160} 161 162 163nxt_int_t 164nxt_var_register(nxt_var_decl_t *decl, size_t n) 165{ 166 nxt_uint_t i; 167 nxt_lvlhsh_query_t lhq; --- 257 unchanged lines hidden (view full) --- 425 426 query = *query_p; 427 428 if (*query_p == NULL) { 429 query = nxt_mp_zget(mp, sizeof(nxt_var_query_t)); 430 if (nxt_slow_path(query == NULL)) { 431 return NXT_ERROR; 432 } |
435 436 nxt_array_init(&query->values, mp, sizeof(nxt_var_value_t)); 437 nxt_array_init(&query->parts, mp, sizeof(nxt_str_t *)); 438 439 } else { 440 nxt_array_reset(&query->values); | |
441 } 442 | 433 } 434 |
435 query->pool = mp; |
|
443 query->ctx = ctx; 444 445 *query_p = query; 446 447 return NXT_OK; 448} 449 450 451void 452nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var, 453 nxt_str_t *str) 454{ | 436 query->ctx = ctx; 437 438 *query_p = query; 439 440 return NXT_OK; 441} 442 443 444void 445nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var, 446 nxt_str_t *str) 447{ |
455 uint32_t index; 456 nxt_mp_t *mp; 457 nxt_str_t *value; 458 nxt_int_t ret; 459 nxt_uint_t i; 460 nxt_var_sub_t *subs; 461 nxt_var_value_t *val; | 448 u_char *p, *src; 449 size_t length, last, next; 450 nxt_str_t *value, **part; 451 nxt_uint_t i; 452 nxt_array_t parts; 453 nxt_var_sub_t *subs; |
462 463 if (nxt_var_is_const(var)) { 464 nxt_var_raw(var, str); 465 return; 466 } 467 468 if (nxt_slow_path(query->failed)) { 469 return; 470 } 471 | 454 455 if (nxt_var_is_const(var)) { 456 nxt_var_raw(var, str); 457 return; 458 } 459 460 if (nxt_slow_path(query->failed)) { 461 return; 462 } 463 |
472 mp = query->values.mem_pool; | 464 nxt_memzero(&parts, sizeof(nxt_array_t)); 465 nxt_array_init(&parts, query->pool, sizeof(nxt_str_t *)); 466 |
473 subs = nxt_var_subs(var); | 467 subs = nxt_var_subs(var); |
474 value = query->spare; | |
475 | 468 |
469 length = var->length; 470 |
|
476 for (i = 0; i < var->vars; i++) { | 471 for (i = 0; i < var->vars; i++) { |
472 value = nxt_var_cache_value(task, query, subs[i].index); 473 if (nxt_slow_path(value == NULL)) { 474 goto fail; 475 } |
|
477 | 476 |
478 if (value == NULL) { 479 value = nxt_mp_zget(mp, sizeof(nxt_str_t)); 480 if (nxt_slow_path(value == NULL)) { 481 goto fail; 482 } | 477 part = nxt_array_add(&parts); 478 if (nxt_slow_path(part == NULL)) { 479 goto fail; |
483 } 484 | 480 } 481 |
485 index = subs[i].index; | 482 *part = value; |
486 | 483 |
487 ret = nxt_var_cache_add(&query->cache, index, value, mp); | 484 length += value->length - subs[i].length; 485 } |
488 | 486 |
489 if (ret != NXT_OK) { 490 if (nxt_slow_path(ret == NXT_ERROR)) { 491 goto fail; 492 } | 487 p = nxt_mp_nget(query->pool, length + var->strz); 488 if (nxt_slow_path(p == NULL)) { 489 goto fail; 490 } |
493 | 491 |
494 continue; /* NXT_DECLINED */ 495 } | 492 str->length = length; 493 str->start = p; |
496 | 494 |
497 ret = nxt_var_index[index](task, value, query->ctx); 498 if (nxt_slow_path(ret != NXT_OK)) { 499 goto fail; | 495 part = parts.elts; 496 src = nxt_var_raw_start(var); 497 498 last = 0; 499 500 for (i = 0; i < var->vars; i++) { 501 next = subs[i].position; 502 503 if (next != last) { 504 p = nxt_cpymem(p, &src[last], next - last); |
500 } 501 | 505 } 506 |
502 value = NULL; | 507 p = nxt_cpymem(p, part[i]->start, part[i]->length); 508 509 last = next + subs[i].length; |
503 } 504 | 510 } 511 |
505 query->spare = value; | 512 if (last != var->length) { 513 p = nxt_cpymem(p, &src[last], var->length - last); 514 } |
506 | 515 |
507 val = nxt_array_add(&query->values); 508 if (nxt_slow_path(val == NULL)) { 509 goto fail; | 516 if (var->strz) { 517 *p = '\0'; |
510 } 511 | 518 } 519 |
512 val->var = var; 513 val->value = str; | 520 nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, str); |
514 515 return; 516 517fail: 518 519 query->failed = 1; 520} 521 522 523void 524nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data, 525 nxt_work_handler_t ready, nxt_work_handler_t error) 526{ 527 query->data = data; 528 query->ready = ready; 529 query->error = error; 530 531 if (query->waiting == 0) { | 521 522 return; 523 524fail: 525 526 query->failed = 1; 527} 528 529 530void 531nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data, 532 nxt_work_handler_t ready, nxt_work_handler_t error) 533{ 534 query->data = data; 535 query->ready = ready; 536 query->error = error; 537 538 if (query->waiting == 0) { |
532 nxt_var_query_finish(task, query); | 539 nxt_work_queue_add(&task->thread->engine->fast_work_queue, 540 query->failed ? query->error : query->ready, 541 task, query->ctx, query->data); |
533 } 534} 535 536 537void 538nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query, 539 nxt_bool_t failed) 540{ 541 query->failed |= failed; 542 543 if (--query->waiting == 0) { | 542 } 543} 544 545 546void 547nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query, 548 nxt_bool_t failed) 549{ 550 query->failed |= failed; 551 552 if (--query->waiting == 0) { |
544 nxt_var_query_finish(task, query); | 553 nxt_work_queue_add(&task->thread->engine->fast_work_queue, 554 query->failed ? query->error : query->ready, 555 task, query->ctx, query->data); |
545 } 546} | 556 } 557} |
547 548 549static void 550nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query) 551{ 552 u_char *p, *src; 553 size_t length, last, next; 554 nxt_str_t *str, **part; 555 nxt_var_t *var; 556 nxt_uint_t i, j; 557 nxt_var_sub_t *subs; 558 nxt_var_value_t *val; 559 560 if (query->failed) { 561 goto done; 562 } 563 564 val = query->values.elts; 565 566 for (i = 0; i < query->values.nelts; i++) { 567 var = val[i].var; 568 569 subs = nxt_var_subs(var); 570 length = var->length; 571 572 for (j = 0; j < var->vars; j++) { 573 str = nxt_var_cache_find(&query->cache, subs[j].index); 574 575 nxt_assert(str != NULL); 576 577 part = nxt_array_add(&query->parts); 578 579 if (nxt_slow_path(part == NULL)) { 580 query->failed = 1; 581 goto done; 582 } 583 584 *part = str; 585 586 length += str->length - subs[j].length; 587 } 588 589 p = nxt_mp_nget(query->values.mem_pool, length + var->strz); 590 if (nxt_slow_path(p == NULL)) { 591 query->failed = 1; 592 goto done; 593 } 594 595 val[i].value->length = length; 596 val[i].value->start = p; 597 598 part = query->parts.elts; 599 src = nxt_var_raw_start(var); 600 601 last = 0; 602 603 for (j = 0; j < var->vars; j++) { 604 next = subs[j].position; 605 606 if (next != last) { 607 p = nxt_cpymem(p, &src[last], next - last); 608 } 609 610 p = nxt_cpymem(p, part[j]->start, part[j]->length); 611 612 last = next + subs[j].length; 613 } 614 615 if (last != var->length) { 616 p = nxt_cpymem(p, &src[last], var->length - last); 617 } 618 619 if (var->strz) { 620 *p = '\0'; 621 } 622 623 nxt_array_reset(&query->parts); 624 625 nxt_debug(task, "var: \"%*s\" -> \"%V\"", var->length, src, 626 val[i].value); 627 } 628 629done: 630 631 nxt_work_queue_add(&task->thread->engine->fast_work_queue, 632 query->failed ? query->error : query->ready, 633 task, query->ctx, query->data); 634} | |