static inline void sp_csv_filter_ctor(sp_csv_filter_t *self) { self->input = 0; self->output = 0; self->table = csv_create(); str_array_ctor(&self->expressions); }
void ia_histogram_rusage(const iaconfig *config, const iarusage *start, const iarusage *fihish) { printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> rusage\n"); FILE* csv = csv_create(config, "rusage"); printf("iops: read %ld, write %ld, page %ld\n", fihish->iops_read - start->iops_read, fihish->iops_write - start->iops_write, fihish->iops_page - start->iops_page ); printf("cpu: user %f, system %f\n", (fihish->cpu_user_ns - start->cpu_user_ns) / (double) S, (fihish->cpu_kernel_ns - start->cpu_kernel_ns) / (double) S ); const double mb = 1ul << 20; printf("space: disk %f, ram %f\n", (fihish->disk - start->disk) / mb, (fihish->ram - start->ram) / mb); if (csv) { fprintf(csv, "%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s\n", "iops_read", "iops_write", "iops_page", "cpu_user_ns", "cpu_kernel_ns", "disk", "ram" ); fprintf(csv, "%zu,\t%zu,\t%zu,\t%e,\t%e,\t%e,\t%e\n", fihish->iops_read - start->iops_read, fihish->iops_write - start->iops_write, fihish->iops_page - start->iops_page, (fihish->cpu_user_ns - start->cpu_user_ns) * 1e-9, (fihish->cpu_kernel_ns - start->cpu_kernel_ns) * 1e-9, (fihish->disk - start->disk) / mb, (fihish->ram - start->ram) / mb ); fclose(csv); } }
/* loads a CSV file from disk */ csv_file *csv_load(const char *filename, int *err, int *line) { csv_file *csv; char *buffer, *p; int r = 0, c = 0; if(err) *err = ER_OK; if(line) *line = 1; if(!filename) RETERR(ER_INV_PARAM); csv = csv_create(0,0); if(!csv) RETERR(ER_MEM_FAIL); /* My approach is to read the entire file into memory and then * parse it from there. * I Acknowledge that this is not the most efficient way of doing it, * but it does simplify the parsing somewhat. */ buffer = my_readfile(filename); if(!buffer) ERREND(ER_IOR_FAIL); for(p = buffer; *p;) { if(strchr(" \t",p[0])) { /* This is to prevent space between the start of a field and a " from confusing the parser */ char *q; for(q = p + 1; strchr(" \t",q[0]); q++); if(q[0] == '\"') p = q; } if(!strncmp(p,"\r\n", 2)) { /* official line endings */ r++; c = 0; p+=2; if(line) (*line)++; } else if(strchr("\r\n",p[0])) { /* alternative line endings */ r++; c = 0; p++; if(line) (*line)++; } else if(*p == ',') { /* A new or empty field */ c++; p++; } else if(*p == '\"') { /* A quoted field */ char *q = p, *s, *t; do { q++; if(*q == '\0') ERREND(ER_EXPECTED_EOS); else if(q[0] == '\"' && q[1] == '\"') q+=2; } while(*q != '\"'); s = malloc(q - p); if(!s) ERREND(ER_MEM_FAIL); t = s; p++; while(p < q) { if(*p == '\"' && *(p+1) == '\"') { *(t++) = *(p++); p++; } else *(t++) = *(p++); } *t = '\0'; /* Skip any whitespace after the closing quote */ for(p++; p[0] && !strchr(",\r\n",p[0]);p++) if(!strchr(" \t",p[0])) ERREND(ER_BAD_QUOTEEND); csv_set_int(csv, r, c, s); } else { /* A normal field */ char *q, *s, *t; #if TRIM_SPACES /* Trim leading whitespace */ while(p[0] && strchr(" \t",p[0])) p++; #endif for(q = p;q[0] && !strchr(",\r\n",q[0]); q++); s = malloc(q - p + 1); if(!s) ERREND(ER_MEM_FAIL); t = s; while(p < q) { *(t++) = *(p++); } *t = '\0'; #if TRIM_SPACES /* Trim trailing whitespace */ while(t > s && strchr(" \t",t[-1])) *(--t) = '\0'; #endif csv_set_int(csv, r, c, s); } } free(buffer); return csv; error: csv_free(csv); return NULL; }
void ia_histogram_print(const iaconfig *config) { iahistogram *h; const ia_timestamp_t wall_ns = global.checkpoint_ns - global.starting_point; const double wall = wall_ns / (double) S; for (h = global.per_bench; h < global.per_bench + IA_MAX; ++h) { if (! h->enabled || ! h->acc.n) continue; const char *name = ia_benchmarkof(h->bench); printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> %s(%zu)\n", name, h->acc.n); FILE* csv = csv_create(config, name); printf("[%8s %8s ]%16s%8s\n", "ltn_from", "ltn_to", "ops_count", "%"); if (csv) fprintf(csv, "%s,\t%s,\t%s,\t%s\n", "ltn_open", "ltn_close", "ops_count", "%"); printf("------------------------------------------------\n"); int i; char line[1024], *s; uint64_t n = 0; for (i = 0; i < ST_HISTOGRAM_COUNT; i++) { if (! h->buckets[i]) continue; n += h->buckets[i]; s = line; s += snprintf(s, line + sizeof(line) - s, "["); s += snpf_lat(s, line + sizeof(line) - s, (i > 0) ? ia_histogram_buckets[i - 1] : 0); s += snprintf(s, line + sizeof(line) - s, ","); s += snpf_lat(s, line + sizeof(line) - s, ia_histogram_buckets[i] - 1); s += snprintf(s, line + sizeof(line) - s, " ]%16zu%7.2f%%", h->buckets[i], h->buckets[i] * 1e2 / h->acc.n); printf("%s\n", line); if(csv) fprintf(csv, "%e,\t%e,\t%zu,\t%e\n", ((i > 0) ? ia_histogram_buckets[i - 1] : 0) / (double) S, (ia_histogram_buckets[i] - 1) / (double) S, h->buckets[i], h->buckets[i] * 1e2 / h->acc.n ); } printf("------------------------------------------------\n"); snpf_lat(line, sizeof(line), h->acc.latency_sum_ns); printf("total:%16s %16zu%7.2f%%\n", line, n, n * 1e2 / h->acc.n); snpf_lat(line, sizeof(line), h->whole_min); printf("min latency:%s/op\n", line); const ia_timestamp_t avg = h->acc.latency_sum_ns / h->acc.n; snpf_lat(line, sizeof(line), avg); printf("avg latency:%s/op\n", line); const ia_timestamp_t rms = sqrt(h->acc.latency_sum_square / h->acc.n); snpf_lat(line, sizeof(line), rms); printf("rms latency:%s/op\n", line); snpf_lat(line, sizeof(line), h->whole_max); printf("max latency:%s/op\n", line); const double rps = h->acc.n / wall; snpf_val(line, sizeof(line), rps, ""); printf(" throughput:%sops/s\n", line); if (csv) { fprintf(csv, "\n%s,\t%s,\t%s,\t%s,\t%s\n", "ltn_min", "ltn_avg", "ltn_rms", "ltn_max", "throughput"); fprintf(csv, "%e,\t%e\t%e\t%e,\t%e\n", h->whole_min / (double) S, avg / (double) S, rms / (double) S, h->whole_max / (double) S, rps ); fclose(csv); } } }
void ia_histogram_csvopen(const iaconfig *config) { if (config->csv_prefix && !global.csv_timeline) global.csv_timeline = csv_create(config, "timeline"); }