[core] use stack w/ pcre_exec unless save captures
use stack w/ pcre_exec unless saving captures from config conditions reduce memory allocations per request where lighttpd.conf does not contain url.redirect or url.rewrite rules where replacements reference a match of the enclosing lighttpd.conf condition (e.g. %0, %1, %2 ...) move cond_cache_t 'patterncount' to cond_match_t 'captures' While cond_match_t is no longer sized power-2, it is generally expected to be used much less frequently than before (which was all the time), since it is now used only with url.redirect or url.rewrite with references %0, %1, %2, ...personal/stbuehler/tests-path
parent
3b3574c5e6
commit
6d47d4c699
|
@ -642,19 +642,22 @@ void config_cond_cache_reset(request_st * const r) {
|
|||
|
||||
static int config_pcre_match(request_st * const r, const data_config * const dc, const buffer * const b) {
|
||||
#ifdef HAVE_PCRE_H
|
||||
if (__builtin_expect( (0 == dc->capture_idx), 1)) {
|
||||
int matches[3 * 10];
|
||||
return pcre_exec(dc->regex, dc->regex_study, BUF_PTR_LEN(b), 0, 0,
|
||||
matches, sizeof(matches)/sizeof(*matches));
|
||||
}
|
||||
|
||||
#ifndef elementsof
|
||||
#define elementsof(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
cond_match_t * const cond_match =
|
||||
r->cond_match[dc->capture_idx] = r->cond_match_data + dc->capture_idx;
|
||||
cond_match->comp_value = b; /*holds pointer to b (!) for pattern subst*/
|
||||
/* Note: patterncount is in cond_cache_t instead of cond_match_t only
|
||||
* so that both structures are sized power-2 for efficient array access */
|
||||
cond_cache_t * const cache = &r->cond_cache[dc->context_ndx];
|
||||
cache->patterncount =
|
||||
cond_match->captures =
|
||||
pcre_exec(dc->regex, dc->regex_study, BUF_PTR_LEN(b), 0, 0,
|
||||
cond_match->matches, elementsof(cond_match->matches));
|
||||
return cache->patterncount;
|
||||
return cond_match->captures;
|
||||
#else
|
||||
UNUSED(r);
|
||||
UNUSED(dc);
|
||||
|
|
|
@ -1229,19 +1229,7 @@ int config_finalize(server *srv, const buffer *default_server_tag) {
|
|||
}
|
||||
|
||||
/* adjust cond_match_data list size if regex config conditions present */
|
||||
if (srv->config_context->used > 1) {
|
||||
const data_config *dcrx = NULL;
|
||||
for (uint32_t i = 1; i < srv->config_context->used; ++i) {
|
||||
const data_config * const dc =
|
||||
(data_config *)srv->config_context->data[i];
|
||||
if ((dc->cond==CONFIG_COND_MATCH || dc->cond==CONFIG_COND_NOMATCH)
|
||||
&& 0 == dc->capture_idx) {
|
||||
dcrx = dc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dcrx || srv->config_captures) ++srv->config_captures;
|
||||
}
|
||||
if (srv->config_captures) ++srv->config_captures;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ static void pcre_keyvalue_buffer_append_match(buffer *b, const char **list, int
|
|||
static void pcre_keyvalue_buffer_append_ctxmatch(buffer *b, const pcre_keyvalue_ctx *ctx, unsigned int num, int flags) {
|
||||
const struct cond_match_t * const cache = ctx->cache;
|
||||
if (!cache) return; /* no enclosing match context */
|
||||
if ((int)num < ctx->cond_match_count) {
|
||||
if ((int)num < cache->captures) {
|
||||
const int off = cache->matches[(num <<= 1)]; /*(num *= 2)*/
|
||||
const int len = cache->matches[num+1] - off;
|
||||
burl_append(b, cache->comp_value->ptr + off, (size_t)len, flags);
|
||||
|
|
|
@ -12,7 +12,6 @@ struct pcre_keyvalue; /* declaration */
|
|||
typedef struct pcre_keyvalue_ctx {
|
||||
struct cond_match_t *cache;
|
||||
struct burl_parts_t *burl;
|
||||
int cond_match_count;
|
||||
int m;
|
||||
} pcre_keyvalue_ctx;
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ static int mod_dirlisting_exclude(pcre_keyvalue_buffer * const kvb, const char *
|
|||
* must have been configured with empty kvb 'value' during init)*/
|
||||
buffer input = { NULL, len+1, 0 };
|
||||
*(const char **)&input.ptr = name;
|
||||
pcre_keyvalue_ctx ctx = { NULL, NULL, 0, -1 };
|
||||
pcre_keyvalue_ctx ctx = { NULL, NULL, -1 };
|
||||
#ifdef __COVERITY__
|
||||
/*(again, must have been configured w/ empty kvb 'value' during init)*/
|
||||
struct cond_match_t cache;
|
||||
|
|
|
@ -169,8 +169,6 @@ URIHANDLER_FUNC(mod_redirect_uri_handler) {
|
|||
|
||||
ctx.cache = NULL;
|
||||
if (p->conf.redirect->x0) { /*(p->conf.redirect->x0 is capture_idx)*/
|
||||
ctx.cond_match_count =
|
||||
r->cond_cache[p->conf.redirect->cfgidx].patterncount;
|
||||
ctx.cache = r->cond_match[p->conf.redirect->x0];
|
||||
}
|
||||
ctx.burl = &burl;
|
||||
|
|
|
@ -291,8 +291,6 @@ static handler_t process_rewrite_rules(request_st * const r, plugin_data *p, con
|
|||
|
||||
ctx.cache = NULL;
|
||||
if (kvb->x0) { /*(kvb->x0 is capture_idx)*/
|
||||
ctx.cond_match_count =
|
||||
r->cond_cache[kvb->cfgidx].patterncount;
|
||||
ctx.cache = r->cond_match[kvb->x0];
|
||||
}
|
||||
ctx.burl = &burl;
|
||||
|
|
|
@ -185,7 +185,7 @@ static int mod_trigger_b4_dl_init_regex(server * const srv, config_plugin_value_
|
|||
static int mod_trigger_b4_dl_match(pcre_keyvalue_buffer * const kvb, const buffer * const input) {
|
||||
/*(re-use keyvalue.[ch] for match-only;
|
||||
* must have been configured with empty kvb 'value' during init)*/
|
||||
pcre_keyvalue_ctx ctx = { NULL, NULL, 0, -1 };
|
||||
pcre_keyvalue_ctx ctx = { NULL, NULL, -1 };
|
||||
#ifdef __COVERITY__
|
||||
/*(again, must have been configured w/ empty kvb 'value' during init)*/
|
||||
struct cond_match_t cache;
|
||||
|
|
|
@ -163,16 +163,13 @@ typedef struct cond_cache_t {
|
|||
int8_t result; /*(cond_result_t)*/
|
||||
/* result without preconditions (must never be "skip") */
|
||||
int8_t local_result; /*(cond_result_t)*/
|
||||
int16_t patterncount;
|
||||
} cond_cache_t; /* 8 bytes (2^3) */
|
||||
} cond_cache_t; /* 2 bytes (2^1) */
|
||||
|
||||
typedef struct cond_match_t {
|
||||
const buffer *comp_value; /* just a pointer */
|
||||
#if !(defined(_LP64) || defined(__LP64__) || defined(_WIN64)) /*(not 64-bit)*/
|
||||
int dummy_alignment; /*(for alignment in 32-bit)*/
|
||||
#endif
|
||||
int captures;
|
||||
int matches[3 * 10];
|
||||
} cond_match_t; /* 128 bytes (2^7) */
|
||||
} cond_match_t;
|
||||
|
||||
int config_check_cond(request_st *r, int context_ndx);
|
||||
|
||||
|
|
|
@ -61,10 +61,10 @@ static void test_keyvalue_pcre_keyvalue_buffer_process (void) {
|
|||
buffer_copy_string_len(scheme, CONST_STR_LEN("http"));
|
||||
buffer_copy_string_len(authority, CONST_STR_LEN("www.example.com"));
|
||||
/* model outer conditional match of $HTTP["host"] =~ "^(www).example.com$" */
|
||||
ctx.cond_match_count = 2;
|
||||
ctx.cache = &cache;
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
cache.comp_value = authority;
|
||||
cache.captures = 2;
|
||||
cache.matches[0] = 0;
|
||||
cache.matches[1] = 15;
|
||||
cache.matches[2] = 0;
|
||||
|
|
Loading…
Reference in New Issue