diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmlogreduce/rewrite.c | |
download | pcp-debian.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmlogreduce/rewrite.c')
-rw-r--r-- | src/pmlogreduce/rewrite.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/pmlogreduce/rewrite.c b/src/pmlogreduce/rewrite.c new file mode 100644 index 0000000..eae00e4 --- /dev/null +++ b/src/pmlogreduce/rewrite.c @@ -0,0 +1,178 @@ +#include "pmlogreduce.h" +#include <inttypes.h> + +static pmResult *orp; + +/* + * Must either re-write the pmResult, or return NULL for non-fatal + * errors, else report and exit for catastrophic errors ... + */ +pmResult * +rewrite(pmResult *rp) +{ + int i; + int sts; + + if ((orp = (pmResult *)malloc(sizeof(pmResult) + + (rp->numpmid - 1) * sizeof(pmValueSet *))) == NULL) { + fprintf(stderr, + "%s: rewrite: cannot malloc pmResult for %d metrics\n", + pmProgname, rp->numpmid); + exit(1); + } + orp->numpmid = 0; + orp->timestamp = rp->timestamp; /* struct assignment */ + + for (i = 0; i < rp->numpmid; i++) { + metric_t *mp; + value_t *vp; + pmValueSet *vsp = rp->vset[i]; + pmValueSet *ovsp; + int j; + int need; + + if (pmidlist[i] != vsp->pmid) { + fprintf(stderr, + "%s: rewrite: Arrgh, mismatched PMID %s vs %s\n", + pmProgname, pmIDStr(pmidlist[i]), pmIDStr(vsp->pmid)); + exit(1); + } + + if (vsp->numval > 0) + need = (vsp->numval - 1) * sizeof(pmValue); + else + need = 0; + ovsp = (pmValueSet *)malloc(sizeof(pmValueSet) + + need*sizeof(pmValue)); + if (ovsp == NULL) { + __uint64_t bytes = (sizeof(pmValueSet) + need * sizeof(pmValue)); + fprintf(stderr, + "%s: rewrite: Arrgh, cannot malloc %"PRIi64" bytes for ovsp\n", + pmProgname, bytes); + exit(1); + } + ovsp->pmid = vsp->pmid; + ovsp->valfmt = vsp->valfmt; + if (vsp->numval <= 0) { + ovsp->numval = vsp->numval; + orp->vset[orp->numpmid] = ovsp; + orp->numpmid++; + } + else { + ovsp->numval = 0; + mp = &metriclist[i]; + if (mp->mode != MODE_SKIP) { + for (j = 0; j < vsp->numval; j++) { + for (vp = mp->first; vp != NULL; vp = vp->next) { + if (vp->inst == vsp->vlist[j].inst) + break; + } + if (vp == NULL) { + fprintf(stderr, + "%s: rewrite: Arrgh: cannot find inst %d in value_t list for %s (%s)\n", + pmProgname, vsp->vlist[j].inst, namelist[i], pmIDStr(vsp->pmid)); + exit(1); + } + if ((vp->control & (V_SEEN|V_INIT)) == 0) + continue; + /* + * we've seen this metric-instance pair in the last + * interval, or it is the first time for this one + */ + if (mp->mode == MODE_REWRITE) { + pmAtomValue av; + int k; + sts = pmExtractValue(vsp->valfmt, &vsp->vlist[j], mp->idesc.type, &av, mp->odesc.type); + if (sts < 0) { + fprintf(stderr, + "%s: rewrite: pmExtractValue failed for pmid %s value %d: %s\n", + pmProgname, pmIDStr(vsp->pmid), j, pmErrStr(sts)); + exit(1); + } + ovsp->pmid = vsp->pmid; + ovsp->vlist[ovsp->numval].inst = vsp->vlist[j].inst; + k = __pmStuffValue(&av, &ovsp->vlist[ovsp->numval], mp->odesc.type); + if (k < 0) { + fprintf(stderr, + "%s: rewrite: __pmStuffValue failed for pmid %s value %d: %s\n", + pmProgname, pmIDStr(vsp->pmid), j, pmErrStr(sts)); + exit(1); + } + if (ovsp->numval == 0) + ovsp->valfmt = k; + ovsp->numval++; + vp->timestamp = rp->timestamp; + vp->value = av; + } + else { + ovsp->vlist[ovsp->numval] = vsp->vlist[j]; + ovsp->numval++; + } + vp->control &= ~V_INIT; + } + } + if (ovsp->numval > 0) { + orp->vset[orp->numpmid] = ovsp; + orp->numpmid++; + } + else + free(ovsp); + } + } + + if (orp->numpmid == 0) { + /* + * very unlikely that all metrics are either skipped or have + * no values, but it might happen ... do not allow this record + * to be written because it looks like a "mark" record with + * numpmid == 0 + */ + free(orp); + orp = NULL; + } + + return orp; +} + +void +rewrite_free(void) +{ + int i; + + if (orp == NULL) + return; + + for (i = 0; i < orp->numpmid; i++) { + pmValueSet *vsp = orp->vset[i]; + int j; + metric_t *mp; + + for (j = 0; j < numpmid; j++) { + if (vsp->pmid == pmidlist[j]) + break; + } + if (j == numpmid) { + fprintf(stderr, + "%s: rewrite_free: Arrgh, cannot find pmid %s in pmidlist[]\n", + pmProgname, pmIDStr(vsp->pmid)); + exit(1); + } + mp = &metriclist[j]; + + if (vsp->numval > 0 && mp->mode == MODE_REWRITE) { + /* + * MODE_REWRITE implies the value was promoted to 64-bit + * and the pval in the pmResult came from the __pmStuffValue() + * call above, so free it here + */ + for (j = 0; j < vsp->numval; j++) { + free(vsp->vlist[j].value.pval); + } + } + + free(vsp); + } + + free(orp); + orp = NULL; +} |