Commit 436707b7 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Minimize use of "pending" buffer and reduce number of (effective)

calls to the 'mark' functions as much as possible.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5760 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 218b7416
...@@ -89,6 +89,8 @@ const char *hack_p; ...@@ -89,6 +89,8 @@ const char *hack_p;
const char *until_p; const char *until_p;
const char *until_s; const char *until_s;
int in_esi_tag;
const char *esicmt; const char *esicmt;
const char *esicmt_p; const char *esicmt_p;
...@@ -105,6 +107,11 @@ const char *hack_p; ...@@ -105,6 +107,11 @@ const char *hack_p;
dostuff_f *dostuff; dostuff_f *dostuff;
struct vsb *include_src; struct vsb *include_src;
unsigned nm_skip;
unsigned nm_verbatim;
unsigned nm_pending;
int last_mark;
}; };
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
...@@ -362,13 +369,23 @@ vep_mark_common(struct vep_state *vep, const char *p, int skip) ...@@ -362,13 +369,23 @@ vep_mark_common(struct vep_state *vep, const char *p, int skip)
static void static void
vep_mark_verbatim(struct vep_state *vep, const char *p) vep_mark_verbatim(struct vep_state *vep, const char *p)
{ {
if (vep->last_mark == 0 && p == vep->ver_p)
return;
//printf("MARK VERB %d %s <%.*s>\n", vep->remove, vep->state, (int)(p - vep->ver_p), vep->ver_p);
vep_mark_common(vep, p, 0); vep_mark_common(vep, p, 0);
vep->nm_verbatim++;
vep->last_mark = 0;
} }
static void static void
vep_mark_skip(struct vep_state *vep, const char *p) vep_mark_skip(struct vep_state *vep, const char *p)
{ {
if (vep->last_mark == 1 && p == vep->ver_p)
return;
//printf("MARK SKIP %d %s <%.*s>\n", vep->remove, vep->state, (int)(p - vep->ver_p), vep->ver_p);
vep_mark_common(vep, p, 1); vep_mark_common(vep, p, 1);
vep->nm_skip++;
vep->last_mark = 1;
} }
static void static void
...@@ -376,16 +393,20 @@ vep_mark_pending(struct vep_state *vep, const char *p) ...@@ -376,16 +393,20 @@ vep_mark_pending(struct vep_state *vep, const char *p)
{ {
ssize_t l; ssize_t l;
if (vep->last_mark == 2 && p == vep->ver_p)
return;
AN(vep->ver_p); AN(vep->ver_p);
l = p - vep->ver_p; l = p - vep->ver_p;
if (l == 0) if (l == 0)
return; return;
// printf("MARK PEND %d %s <%.*s>\n", vep->remove, vep->state, (int)l, vep->ver_p);
assert(l >= 0); assert(l >= 0);
vep->crcp = crc32(vep->crcp, (const void *)vep->ver_p, l); vep->crcp = crc32(vep->crcp, (const void *)vep->ver_p, l);
vep->ver_p = p; vep->ver_p = p;
vep->o_pending += l; vep->o_pending += l;
fflush(stdout); vep->nm_pending++;
vep->last_mark = 2;
} }
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
...@@ -559,13 +580,10 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -559,13 +580,10 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
* If the first non-whitespace char is different * If the first non-whitespace char is different
* from '<' we assume this is not XML. * from '<' we assume this is not XML.
*/ */
while (p < e && vct_islws(*p)) { while (p < e && vct_islws(*p))
p++; p++;
vep_mark_verbatim(vep, p); vep_mark_verbatim(vep, p);
}
if (p < e && *p == '<') { if (p < e && *p == '<') {
if (!vep->remove)
vep_mark_verbatim(vep, p);
p++; p++;
vep->state = VEP_STARTTAG; vep->state = VEP_STARTTAG;
} else if (p < e) { } else if (p < e) {
...@@ -579,6 +597,7 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -579,6 +597,7 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
* vfp_esi_end() will handle the rest * vfp_esi_end() will handle the rest
*/ */
p = e; p = e;
vep_mark_verbatim(vep, p);
/****************************************************** /******************************************************
* SECTION B * SECTION B
...@@ -588,8 +607,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -588,8 +607,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
if (params->esi_syntax & 0x2) { if (params->esi_syntax & 0x2) {
p++; p++;
vep->state = VEP_NEXTTAG; vep->state = VEP_NEXTTAG;
if (!vep->remove)
vep_mark_verbatim(vep, p);
} else { } else {
vep->tag_i = 0; vep->tag_i = 0;
while (p < e) { while (p < e) {
...@@ -598,9 +615,9 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -598,9 +615,9 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
break; break;
} }
} }
if (p < e && !vep->remove)
vep_mark_verbatim(vep, p);
} }
if (p == e && !vep->remove)
vep_mark_verbatim(vep, p);
} else if (vep->state == VEP_NEXTTAG) { } else if (vep->state == VEP_NEXTTAG) {
/* /*
* Hunt for start of next tag and keep an eye * Hunt for start of next tag and keep an eye
...@@ -611,35 +628,38 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -611,35 +628,38 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
vep->attr = NULL; vep->attr = NULL;
vep->dostuff = NULL; vep->dostuff = NULL;
while (p < e && *p != '<') { while (p < e && *p != '<') {
if (vep->esicmt_p != NULL && if (vep->esicmt_p == NULL) {
*p == *vep->esicmt_p++) {
p++; p++;
if (*vep->esicmt_p == '\0') { continue;
vep->esicmt = NULL; }
vep->esicmt_p = NULL; if (*p != *vep->esicmt_p) {
/*
* The end of the esicmt
* should not be emitted.
* But the stuff before should
*/
vep_mark_skip(vep, p);
}
} else {
p++; p++;
if (!vep->remove)
vep_mark_verbatim(vep, p);
vep->esicmt_p = vep->esicmt; vep->esicmt_p = vep->esicmt;
continue;
}
if (!vep->remove &&
vep->esicmt_p == vep->esicmt)
vep_mark_verbatim(vep, p);
p++;
if (*++vep->esicmt_p == '\0') {
vep->esicmt = NULL;
vep->esicmt_p = NULL;
/*
* The end of the esicmt
* should not be emitted.
* But the stuff before should
*/
vep_mark_skip(vep, p);
} }
} }
if (p < e && vep->esicmt_p == NULL && !vep->remove)
vep_mark_verbatim(vep, p);
if (p < e) { if (p < e) {
assert(*p == '<');
if (!vep->remove) if (!vep->remove)
vep_mark_verbatim(vep, p); vep_mark_verbatim(vep, p);
assert(*p == '<');
p++; p++;
vep->state = VEP_STARTTAG; vep->state = VEP_STARTTAG;
} } else if (vep->esicmt_p == vep->esicmt && !vep->remove)
vep_mark_verbatim(vep, p);
/****************************************************** /******************************************************
* SECTION C * SECTION C
...@@ -692,12 +712,12 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -692,12 +712,12 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
vep->until_s = VEP_NEXTTAG; vep->until_s = VEP_NEXTTAG;
vep->state = VEP_UNTIL; vep->state = VEP_UNTIL;
} else if (vep->state == VEP_ESITAG) { } else if (vep->state == VEP_ESITAG) {
vep->in_esi_tag = 1;
vep_mark_skip(vep, p); vep_mark_skip(vep, p);
vep->match = vep_match_esi; vep->match = vep_match_esi;
vep->state = VEP_MATCH; vep->state = VEP_MATCH;
} else if (vep->state == VEP_ESIINCLUDE) { } else if (vep->state == VEP_ESIINCLUDE) {
if (vep->remove) { if (vep->remove) {
vep_mark_skip(vep, p);
vep_error(vep, vep_error(vep,
"ESI 1.0 <esi:include> element" "ESI 1.0 <esi:include> element"
" nested in <esi:remove>"); " nested in <esi:remove>");
...@@ -716,7 +736,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -716,7 +736,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
vep->state = VEP_INTAG; vep->state = VEP_INTAG;
} else if (vep->state == VEP_ESICOMMENT) { } else if (vep->state == VEP_ESICOMMENT) {
if (vep->remove) { if (vep->remove) {
vep_mark_skip(vep, p);
vep_error(vep, vep_error(vep,
"ESI 1.0 <esi:comment> element" "ESI 1.0 <esi:comment> element"
" nested in <esi:remove>"); " nested in <esi:remove>");
...@@ -730,7 +749,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -730,7 +749,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
vep->state = VEP_INTAG; vep->state = VEP_INTAG;
} }
} else if (vep->state == VEP_ESIBOGON) { } else if (vep->state == VEP_ESIBOGON) {
vep_mark_skip(vep, p);
vep_error(vep, vep_error(vep,
"ESI 1.0 <esi:bogus> element"); "ESI 1.0 <esi:bogus> element");
vep->state = VEP_TAGERROR; vep->state = VEP_TAGERROR;
...@@ -741,7 +759,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -741,7 +759,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
} else if (vep->state == VEP_INTAG) { } else if (vep->state == VEP_INTAG) {
vep->tag_i = 0; vep->tag_i = 0;
vep_mark_skip(vep, p);
while (p < e && vct_islws(*p) && !vep->emptytag) { while (p < e && vct_islws(*p) && !vep->emptytag) {
p++; p++;
vep->canattr = 1; vep->canattr = 1;
...@@ -756,6 +773,7 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -756,6 +773,7 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
AN(vep->dostuff); AN(vep->dostuff);
vep_mark_skip(vep, p); vep_mark_skip(vep, p);
vep->dostuff(vep, DO_TAG); vep->dostuff(vep, DO_TAG);
vep->in_esi_tag = 0;
vep->state = VEP_NEXTTAG; vep->state = VEP_NEXTTAG;
} else if (p < e && vep->emptytag) { } else if (p < e && vep->emptytag) {
vep_error(vep, vep_error(vep,
...@@ -775,6 +793,7 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -775,6 +793,7 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
if (p < e) { if (p < e) {
p++; p++;
vep_mark_skip(vep, p); vep_mark_skip(vep, p);
vep->in_esi_tag = 0;
vep->state = VEP_NEXTTAG; vep->state = VEP_NEXTTAG;
} }
...@@ -805,7 +824,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -805,7 +824,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
} else if (p < e && vct_issp(*p)) { } else if (p < e && vct_issp(*p)) {
vep->state = VEP_INTAG; vep->state = VEP_INTAG;
} else if (p < e) { } else if (p < e) {
vep_mark_skip(vep, p);
vep_error(vep, vep_error(vep,
"XML 1.0 Illegal attr char"); "XML 1.0 Illegal attr char");
vep->state = VEP_TAGERROR; vep->state = VEP_TAGERROR;
...@@ -822,7 +840,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -822,7 +840,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
vep->attr_delim = ' '; vep->attr_delim = ' ';
vep->state = VEP_ATTRVAL; vep->state = VEP_ATTRVAL;
} else { } else {
vep_mark_skip(vep, p);
vep_error(vep, vep_error(vep,
"XML 1.0 Illegal attribute delimiter"); "XML 1.0 Illegal attribute delimiter");
vep->state = VEP_TAGERROR; vep->state = VEP_TAGERROR;
...@@ -836,7 +853,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -836,7 +853,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
p++; p++;
} }
if (p < e && *p == '>') { if (p < e && *p == '>') {
vep_mark_skip(vep, p);
vep_error(vep, vep_error(vep,
"XML 1.0 Missing end attribute delimiter"); "XML 1.0 Missing end attribute delimiter");
vep->state = VEP_TAGERROR; vep->state = VEP_TAGERROR;
...@@ -852,7 +868,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -852,7 +868,6 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
if (vep->attr_vsb != NULL) { if (vep->attr_vsb != NULL) {
vsb_finish(vep->attr_vsb); vsb_finish(vep->attr_vsb);
AN(vep->dostuff); AN(vep->dostuff);
vep_mark_skip(vep, p);
vep->dostuff(vep, DO_ATTR); vep->dostuff(vep, DO_ATTR);
vep->attr_vsb = NULL; vep->attr_vsb = NULL;
} }
...@@ -921,13 +936,27 @@ vep_parse(struct vep_state *vep, const char *p, size_t l) ...@@ -921,13 +936,27 @@ vep_parse(struct vep_state *vep, const char *p, size_t l)
vep->state = vep->until_s; vep->state = vep->until_s;
break; break;
} }
if (p == e && !vep->remove)
vep_mark_verbatim(vep, p);
} }
} else { } else {
Debug("*** Unknown state %s\n", vep->state); Debug("*** Unknown state %s\n", vep->state);
INCOMPL(); INCOMPL();
} }
} }
vep_mark_pending(vep, p); /*
* We must always mark up the storage we got, try to do so
* in the most efficient way, in particular with respect to
* minimizing and limiting use of pending.
*/
if (p == vep->ver_p)
;
else if (vep->in_esi_tag)
vep_mark_skip(vep, p);
else if (vep->remove)
vep_mark_skip(vep, p);
else
vep_mark_pending(vep, p);
} }
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
...@@ -1056,6 +1085,8 @@ vfp_esi_end(struct sess *sp) ...@@ -1056,6 +1085,8 @@ vfp_esi_end(struct sess *sp)
vep_emit_common(vep, &vep->o_skip, 1); vep_emit_common(vep, &vep->o_skip, 1);
else if (vep->o_verbatim > 0) else if (vep->o_verbatim > 0)
vep_emit_common(vep, &vep->o_verbatim, 0); vep_emit_common(vep, &vep->o_verbatim, 0);
printf("NMARK VER %u SKIP %u PEND %u\n", vep->nm_verbatim, vep->nm_skip, vep->nm_pending);
vsb_finish(vep->vsb); vsb_finish(vep->vsb);
l = vsb_len(vep->vsb); l = vsb_len(vep->vsb);
if (vep->state != VEP_NOTXML && l > 0) { if (vep->state != VEP_NOTXML && l > 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment