summaryrefslogtreecommitdiff
path: root/src/pmlogreduce/rewrite.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
committerIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
commit47e6e7c84f008a53061e661f31ae96629bc694ef (patch)
tree648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmlogreduce/rewrite.c
downloadpcp-debian.tar.gz
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmlogreduce/rewrite.c')
-rw-r--r--src/pmlogreduce/rewrite.c178
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;
+}