r5760 - trunk/varnish-cache/bin/varnishd
phk at varnish-cache.org
phk at varnish-cache.org
Tue Jan 18 15:05:58 CET 2011
Author: phk
Date: 2011-01-18 15:05:58 +0100 (Tue, 18 Jan 2011)
New Revision: 5760
Modified:
trunk/varnish-cache/bin/varnishd/cache_esi_parse.c
Log:
Minimize use of "pending" buffer and reduce number of (effective)
calls to the 'mark' functions as much as possible.
Modified: trunk/varnish-cache/bin/varnishd/cache_esi_parse.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_esi_parse.c 2011-01-18 11:25:47 UTC (rev 5759)
+++ trunk/varnish-cache/bin/varnishd/cache_esi_parse.c 2011-01-18 14:05:58 UTC (rev 5760)
@@ -89,6 +89,8 @@
const char *until_p;
const char *until_s;
+ int in_esi_tag;
+
const char *esicmt;
const char *esicmt_p;
@@ -105,6 +107,11 @@
dostuff_f *dostuff;
struct vsb *include_src;
+
+ unsigned nm_skip;
+ unsigned nm_verbatim;
+ unsigned nm_pending;
+ int last_mark;
};
/*---------------------------------------------------------------------*/
@@ -362,13 +369,23 @@
static void
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->nm_verbatim++;
+ vep->last_mark = 0;
}
static void
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->nm_skip++;
+ vep->last_mark = 1;
}
static void
@@ -376,16 +393,20 @@
{
ssize_t l;
+ if (vep->last_mark == 2 && p == vep->ver_p)
+ return;
AN(vep->ver_p);
l = p - vep->ver_p;
if (l == 0)
return;
+// printf("MARK PEND %d %s <%.*s>\n", vep->remove, vep->state, (int)l, vep->ver_p);
assert(l >= 0);
vep->crcp = crc32(vep->crcp, (const void *)vep->ver_p, l);
vep->ver_p = p;
vep->o_pending += l;
- fflush(stdout);
+ vep->nm_pending++;
+ vep->last_mark = 2;
}
/*---------------------------------------------------------------------
@@ -559,13 +580,10 @@
* If the first non-whitespace char is different
* from '<' we assume this is not XML.
*/
- while (p < e && vct_islws(*p)) {
+ while (p < e && vct_islws(*p))
p++;
- vep_mark_verbatim(vep, p);
- }
+ vep_mark_verbatim(vep, p);
if (p < e && *p == '<') {
- if (!vep->remove)
- vep_mark_verbatim(vep, p);
p++;
vep->state = VEP_STARTTAG;
} else if (p < e) {
@@ -579,6 +597,7 @@
* vfp_esi_end() will handle the rest
*/
p = e;
+ vep_mark_verbatim(vep, p);
/******************************************************
* SECTION B
@@ -588,8 +607,6 @@
if (params->esi_syntax & 0x2) {
p++;
vep->state = VEP_NEXTTAG;
- if (!vep->remove)
- vep_mark_verbatim(vep, p);
} else {
vep->tag_i = 0;
while (p < e) {
@@ -598,9 +615,9 @@
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) {
/*
* Hunt for start of next tag and keep an eye
@@ -611,35 +628,38 @@
vep->attr = NULL;
vep->dostuff = NULL;
while (p < e && *p != '<') {
- if (vep->esicmt_p != NULL &&
- *p == *vep->esicmt_p++) {
+ if (vep->esicmt_p == NULL) {
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);
- }
- } else {
+ continue;
+ }
+ if (*p != *vep->esicmt_p) {
p++;
- if (!vep->remove)
- vep_mark_verbatim(vep, p);
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) {
- assert(*p == '<');
if (!vep->remove)
vep_mark_verbatim(vep, p);
+ assert(*p == '<');
p++;
vep->state = VEP_STARTTAG;
- }
+ } else if (vep->esicmt_p == vep->esicmt && !vep->remove)
+ vep_mark_verbatim(vep, p);
/******************************************************
* SECTION C
@@ -692,12 +712,12 @@
vep->until_s = VEP_NEXTTAG;
vep->state = VEP_UNTIL;
} else if (vep->state == VEP_ESITAG) {
+ vep->in_esi_tag = 1;
vep_mark_skip(vep, p);
vep->match = vep_match_esi;
vep->state = VEP_MATCH;
} else if (vep->state == VEP_ESIINCLUDE) {
if (vep->remove) {
- vep_mark_skip(vep, p);
vep_error(vep,
"ESI 1.0 <esi:include> element"
" nested in <esi:remove>");
@@ -716,7 +736,6 @@
vep->state = VEP_INTAG;
} else if (vep->state == VEP_ESICOMMENT) {
if (vep->remove) {
- vep_mark_skip(vep, p);
vep_error(vep,
"ESI 1.0 <esi:comment> element"
" nested in <esi:remove>");
@@ -730,7 +749,6 @@
vep->state = VEP_INTAG;
}
} else if (vep->state == VEP_ESIBOGON) {
- vep_mark_skip(vep, p);
vep_error(vep,
"ESI 1.0 <esi:bogus> element");
vep->state = VEP_TAGERROR;
@@ -741,7 +759,6 @@
} else if (vep->state == VEP_INTAG) {
vep->tag_i = 0;
- vep_mark_skip(vep, p);
while (p < e && vct_islws(*p) && !vep->emptytag) {
p++;
vep->canattr = 1;
@@ -756,6 +773,7 @@
AN(vep->dostuff);
vep_mark_skip(vep, p);
vep->dostuff(vep, DO_TAG);
+ vep->in_esi_tag = 0;
vep->state = VEP_NEXTTAG;
} else if (p < e && vep->emptytag) {
vep_error(vep,
@@ -775,6 +793,7 @@
if (p < e) {
p++;
vep_mark_skip(vep, p);
+ vep->in_esi_tag = 0;
vep->state = VEP_NEXTTAG;
}
@@ -805,7 +824,6 @@
} else if (p < e && vct_issp(*p)) {
vep->state = VEP_INTAG;
} else if (p < e) {
- vep_mark_skip(vep, p);
vep_error(vep,
"XML 1.0 Illegal attr char");
vep->state = VEP_TAGERROR;
@@ -822,7 +840,6 @@
vep->attr_delim = ' ';
vep->state = VEP_ATTRVAL;
} else {
- vep_mark_skip(vep, p);
vep_error(vep,
"XML 1.0 Illegal attribute delimiter");
vep->state = VEP_TAGERROR;
@@ -836,7 +853,6 @@
p++;
}
if (p < e && *p == '>') {
- vep_mark_skip(vep, p);
vep_error(vep,
"XML 1.0 Missing end attribute delimiter");
vep->state = VEP_TAGERROR;
@@ -852,7 +868,6 @@
if (vep->attr_vsb != NULL) {
vsb_finish(vep->attr_vsb);
AN(vep->dostuff);
- vep_mark_skip(vep, p);
vep->dostuff(vep, DO_ATTR);
vep->attr_vsb = NULL;
}
@@ -921,13 +936,27 @@
vep->state = vep->until_s;
break;
}
+ if (p == e && !vep->remove)
+ vep_mark_verbatim(vep, p);
}
} else {
Debug("*** Unknown state %s\n", vep->state);
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 @@
vep_emit_common(vep, &vep->o_skip, 1);
else if (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);
l = vsb_len(vep->vsb);
if (vep->state != VEP_NOTXML && l > 0) {
More information about the varnish-commit
mailing list