Commit fb19c2ce authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Refactor adding records to vsl buffers

parent 8e281764
...@@ -110,6 +110,7 @@ vsl_sanity(const struct vsl_log *vsl) ...@@ -110,6 +110,7 @@ vsl_sanity(const struct vsl_log *vsl)
AN(vsl->wlp); AN(vsl->wlp);
AN(vsl->wlb); AN(vsl->wlb);
AN(vsl->wle); AN(vsl->wle);
assert(vsl->wlp <= vsl->wle);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -329,72 +330,81 @@ VSL_Flush(struct vsl_log *vsl, int overflow) ...@@ -329,72 +330,81 @@ VSL_Flush(struct vsl_log *vsl, int overflow)
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* VSL-buffered-txt * Buffered VSLs
*/ */
void static char *
VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t) vslb_get(struct vsl_log *vsl, enum VSL_tag_e tag, unsigned *length)
{ {
unsigned l, mlen; unsigned mlen = cache_param->vsl_reclen;
char *p; char *retval;
vsl_sanity(vsl); vsl_sanity(vsl);
Tcheck(t); if (*length < mlen)
if (vsl_tag_is_masked(tag)) mlen = *length;
return;
mlen = cache_param->vsl_reclen;
/* Truncate */ if (VSL_END(vsl->wlp, mlen) > vsl->wle)
l = Tlen(t); VSL_Flush(vsl, 1);
if (l > mlen - 1)
l = mlen - 1;
assert(vsl->wlp <= vsl->wle); retval = VSL_DATA(vsl->wlp);
/* Flush if necessary */ /* If it still doesn't fit, truncate */
if (VSL_END(vsl->wlp, l + 1) > vsl->wle) if (VSL_END(vsl->wlp, mlen) > vsl->wle)
VSL_Flush(vsl, 1); *length = mlen = ((char *)vsl->wle) - VSL_DATA(vsl->wlp);
assert(VSL_END(vsl->wlp, l + 1) <= vsl->wle);
p = VSL_DATA(vsl->wlp); vsl->wlp = vsl_hdr(tag, vsl->wlp, mlen, vsl->wid);
memcpy(p, t.b, l);
p[l++] = '\0'; /* NUL-terminated */
vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid);
assert(vsl->wlp <= vsl->wle);
vsl->wlr++; vsl->wlr++;
return (retval);
}
static void
vslb_simple(struct vsl_log *vsl, enum VSL_tag_e tag,
unsigned length, const char *str)
{
char *p;
if (length == 0)
length = strlen(str);
length += 1; // NUL
p = vslb_get(vsl, tag, &length);
memcpy(p, str, length - 1);
p[length - 1] = '\0';
if (DO_DEBUG(DBG_SYNCVSL)) if (DO_DEBUG(DBG_SYNCVSL))
VSL_Flush(vsl, 0); VSL_Flush(vsl, 0);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* VSL-buffered-strands * VSL-buffered-txt
*/ */
void void
VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s) VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
{ {
unsigned l, mlen;
vsl_sanity(vsl); Tcheck(t);
if (vsl_tag_is_masked(tag)) if (vsl_tag_is_masked(tag))
return; return;
mlen = cache_param->vsl_reclen;
/* including NUL */ vslb_simple(vsl, tag, Tlen(t), t.b);
l = vmin_t(unsigned, strands_len(s) + 1, mlen); }
assert(vsl->wlp <= vsl->wle); /*--------------------------------------------------------------------
* VSL-buffered-strands
*/
void
VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s)
{
unsigned l;
char *p;
/* Flush if necessary */ if (vsl_tag_is_masked(tag))
if (VSL_END(vsl->wlp, l) > vsl->wle) return;
VSL_Flush(vsl, 1);
assert(VSL_END(vsl->wlp, l) <= vsl->wle);
mlen = strands_cat(VSL_DATA(vsl->wlp), l, s); l = strands_len(s) + 1;
assert(l == mlen); p = vslb_get(vsl, tag, &l);
vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid); (void)strands_cat(p, l, s);
assert(vsl->wlp <= vsl->wle);
vsl->wlr++;
if (DO_DEBUG(DBG_SYNCVSL)) if (DO_DEBUG(DBG_SYNCVSL))
VSL_Flush(vsl, 0); VSL_Flush(vsl, 0);
...@@ -407,14 +417,10 @@ VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s) ...@@ -407,14 +417,10 @@ VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s)
void void
VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap) VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap)
{ {
char *p; char *p, *p1;
const char *u, *f; unsigned n = 0, mlen;
unsigned n, mlen;
txt t;
va_list ap2; va_list ap2;
int first;
vsl_sanity(vsl);
AN(fmt); AN(fmt);
if (vsl_tag_is_masked(tag)) if (vsl_tag_is_masked(tag))
return; return;
...@@ -422,63 +428,43 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap) ...@@ -422,63 +428,43 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap)
/* /*
* If there are no printf-expansions, don't waste time expanding them * If there are no printf-expansions, don't waste time expanding them
*/ */
f = NULL; if (strchr(fmt, '%') == NULL) {
for (u = fmt; *u != '\0'; u++) vslb_simple(vsl, tag, 0, fmt);
if (*u == '%')
f = u;
if (f == NULL) {
t.b = TRUST_ME(fmt);
t.e = TRUST_ME(u);
VSLbt(vsl, tag, t);
return; return;
} }
/*
* If the format is trivial, deal with it directly
*/
if (!strcmp(fmt, "%s")) { if (!strcmp(fmt, "%s")) {
p = va_arg(ap, char *); p1 = va_arg(ap, char *);
t.b = p; vslb_simple(vsl, tag, 0, p1);
t.e = strchr(p, '\0');
VSLbt(vsl, tag, t);
return; return;
} }
assert(vsl->wlp <= vsl->wle); vsl_sanity(vsl);
/* Flush if we can't fit any bytes */ mlen = (char *)vsl->wle - VSL_DATA(vsl->wlp);
if (vsl->wle - vsl->wlp <= VSL_OVERHEAD)
VSL_Flush(vsl, 1);
/* Do the vsnprintf formatting in one or two stages. If the first // First attempt, only if any space at all
stage shows that we overflowed, and the available space to work if (mlen > 0) {
with was less than vsl_reclen, flush and do the formatting
again. */
first = 1;
while (1) {
assert(vsl->wle - vsl->wlp > VSL_OVERHEAD);
mlen = VSL_BYTES((vsl->wle - vsl->wlp) - VSL_OVERHEAD);
if (mlen > cache_param->vsl_reclen)
mlen = cache_param->vsl_reclen;
assert(mlen > 0);
assert(VSL_END(vsl->wlp, mlen) <= vsl->wle);
p = VSL_DATA(vsl->wlp); p = VSL_DATA(vsl->wlp);
va_copy(ap2, ap); va_copy(ap2, ap);
n = vsnprintf(p, mlen, fmt, ap2); n = vsnprintf(p, mlen, fmt, ap2);
va_end(ap2); va_end(ap2);
if (first && n >= mlen && mlen < cache_param->vsl_reclen) {
first = 0;
VSL_Flush(vsl, 1);
continue;
}
break;
} }
if (n > mlen - 1) // Second attempt after a flush
n = mlen - 1; /* we truncate long fields */ if (mlen == 0 || n + 1 > mlen) {
p[n++] = '\0'; /* NUL-terminated */ // Second attempt after a flush
vsl->wlp = vsl_hdr(tag, vsl->wlp, n, vsl->wid); VSL_Flush(vsl, 1);
assert(vsl->wlp <= vsl->wle); mlen = (char *)vsl->wle - VSL_DATA(vsl->wlp);
vsl->wlr++; p = VSL_DATA(vsl->wlp);
n = vsnprintf(p, mlen, fmt, ap);
}
if (n + 1 < mlen)
mlen = n + 1;
(void)vslb_get(vsl, tag, &mlen);
if (DO_DEBUG(DBG_SYNCVSL)) if (DO_DEBUG(DBG_SYNCVSL))
VSL_Flush(vsl, 0); VSL_Flush(vsl, 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