📄 stats.c
字号:
} fprintf(fd, "\n"); } } } fprintf(fd, "%s.end_dist\n", stat->name);}/* print a sparse array distribution */static voidprint_sdist(struct stat_stat_t *stat, /* stat variable */ FILE *fd) /* output stream */{ unsigned int i, bcount, imax, imin; double btotal, bsum, bvar, bavg, bsqsum; struct bucket_t *bucket; int pf = stat->variant.for_sdist.pf; /* count and sum entries */ bcount = 0; btotal = 0.0; bvar = 0.0; bsqsum = 0.0; imax = 0; imin = UINT_MAX; for (i=0; i<HTAB_SZ; i++) { for (bucket = stat->variant.for_sdist.sarr[i]; bucket != NULL; bucket = bucket->next) { bcount++; btotal += bucket->count; /* on-line variance computation, tres cool, no!?! */ bsqsum += ((double)bucket->count * (double)bucket->count); bavg = btotal / (double)bcount; bvar = (bsqsum - ((double)bcount * bavg * bavg)) / (double)(((bcount - 1) > 0) ? (bcount - 1) : 1); if (bucket->index < imin) imin = bucket->index; if (bucket->index > imax) imax = bucket->index; } } /* print header */ fprintf(fd, "\n"); fprintf(fd, "%-22s # %s\n", stat->name, stat->desc); fprintf(fd, "%s.count = %u\n", stat->name, bcount); fprintf(fd, "%s.total = %.0f\n", stat->name, btotal); if (bcount > 0) { fprintf(fd, "%s.imin = %u\n", stat->name, imin); fprintf(fd, "%s.imax = %u\n", stat->name, imax); } else { fprintf(fd, "%s.imin = %d\n", stat->name, -1); fprintf(fd, "%s.imax = %d\n", stat->name, -1); } fprintf(fd, "%s.average = %8.4f\n", stat->name, btotal/bcount); fprintf(fd, "%s.std_dev = %8.4f\n", stat->name, sqrt(bvar)); fprintf(fd, "%s.overflows = 0\n", stat->name); fprintf(fd, "# pdf == prob dist fn, cdf == cumulative dist fn\n"); fprintf(fd, "# %14s ", "index"); if (pf & PF_COUNT) fprintf(fd, "%10s ", "count"); if (pf & PF_PDF) fprintf(fd, "%6s ", "pdf"); if (pf & PF_CDF) fprintf(fd, "%6s ", "cdf"); fprintf(fd, "\n"); fprintf(fd, "%s.start_dist\n", stat->name); if (bcount > 0) { unsigned int bindex; struct bucket_t **barr; /* collect all buckets */ barr = (struct bucket_t **)calloc(bcount, sizeof(struct bucket_t *)); if (!barr) fatal("out of virtual memory"); for (bindex=0,i=0; i<HTAB_SZ; i++) { for (bucket = stat->variant.for_sdist.sarr[i]; bucket != NULL; bucket = bucket->next) { barr[bindex++] = bucket; } } /* sort the array by index */ qsort(barr, bcount, sizeof(struct bucket_t *), (void *)compare_fn); /* print the array */ bsum = 0.0; for (i=0; i<bcount; i++) { bsum += (double)barr[i]->count; if (stat->variant.for_sdist.print_fn) { stat->variant.for_sdist.print_fn(stat, barr[i]->index, barr[i]->count, bsum, btotal); } else { if (stat->format == NULL) { fprintf(fd, "%16u ", barr[i]->index); if (pf & PF_COUNT) fprintf(fd, "%10u ", barr[i]->count); if (pf & PF_PDF) fprintf(fd, "%6.2f ", (double)barr[i]->count/MAX(btotal, 1.0) * 100.0); if (pf & PF_CDF) fprintf(fd, "%6.2f ", bsum/MAX(btotal, 1.0) * 100.0); } else { if (pf == (PF_COUNT|PF_PDF|PF_CDF)) { fprintf(fd, stat->format, barr[i]->index, barr[i]->count, (double)barr[i]->count/MAX(btotal, 1.0) * 100.0, bsum/MAX(btotal, 1.0) * 100.0); } else if (pf == (PF_COUNT|PF_PDF)) { fprintf(fd, stat->format, barr[i]->index, barr[i]->count, (double)barr[i]->count/MAX(btotal, 1.0) * 100.0); } else if (pf == PF_COUNT) { fprintf(fd, stat->format, barr[i]->index, barr[i]->count); } else fatal("distribution format not yet implemented"); } fprintf(fd, "\n"); } } /* all done, release bucket pointer array */ free(barr); } fprintf(fd, "%s.end_dist\n", stat->name);}/* print the value of stat variable STAT */voidstat_print_stat(struct stat_sdb_t *sdb, /* stat database */ struct stat_stat_t *stat,/* stat variable */ FILE *fd) /* output stream */{ struct eval_value_t val; int i; switch (stat->sc) { case sc_int: fprintf(fd, "%-22s ", stat->name); fprintf(fd, stat->format, *stat->variant.for_int.var); fprintf(fd, " # %s", stat->desc); break; case sc_uint: fprintf(fd, "%-22s ", stat->name); fprintf(fd, stat->format, *stat->variant.for_uint.var); fprintf(fd, " # %s", stat->desc); break; case sc_uintarray: fprintf(fd, "%-22s ", stat->name); fprintf(fd, "%12s # %s", " ", stat->desc); fprintf(fd, "\n"); for (i = 0; i < *stat->variant.for_uintarray.num_used_ptr; i++) { fprintf(fd, " pid %-14d ", i); fprintf(fd, stat->format, stat->variant.for_uintarray.var[i]); fprintf(fd, "\n"); } break;#ifdef __GNUC__ case sc_llong: fprintf(fd, "%-22s ", stat->name); fprintf(fd, stat->format, (double)*stat->variant.for_llong.var); fprintf(fd, " # %s", stat->desc); break;#endif /* __GNUC__ */ case sc_float: fprintf(fd, "%-22s ", stat->name); fprintf(fd, stat->format, (double)*stat->variant.for_float.var); fprintf(fd, " # %s", stat->desc); break; case sc_double: fprintf(fd, "%-22s ", stat->name); fprintf(fd, stat->format, *stat->variant.for_double.var); fprintf(fd, " # %s", stat->desc); break; case sc_dist: print_dist(stat, fd); break; case sc_sdist: print_sdist(stat, fd); break; case sc_formula: { /* instantiate a new evaluator to avoid recursion problems */ struct eval_state_t *es = eval_new(stat_eval_ident, sdb); char *endp; fprintf(fd, "%-22s ", stat->name); val = eval_expr(es, stat->variant.for_formula.formula, &endp); if (eval_error != ERR_NOERR || *endp != '\0') fprintf(fd, "<error: %s>", eval_err_str[eval_error]); else fprintf(fd, stat->format, eval_as_double(val)); fprintf(fd, " # %s", stat->desc); /* done with the evaluator */ eval_delete(es); } break; default: panic("bogus stat class"); } fprintf(fd, "\n");}/* print the value of all stat variables in stat database SDB */voidstat_print_stats(struct stat_sdb_t *sdb,/* stat database */ FILE *fd) /* output stream */{ struct stat_stat_t *stat; if (!sdb) { /* no stats */ return; } for (stat=sdb->stats; stat != NULL; stat=stat->next) stat_print_stat(sdb, stat, fd);}/* find a stat variable, returns NULL if it is not found */struct stat_stat_t *stat_find_stat(struct stat_sdb_t *sdb, /* stat database */ char *stat_name) /* stat name */{ struct stat_stat_t *stat; for (stat = sdb->stats; stat != NULL; stat = stat->next) { if (!strcmp(stat->name, stat_name)) break; } return stat;}#ifdef TESTITvoidmain(void){ struct stat_sdb_t *sdb; struct stat_stat_t *stat, *stat1, *stat2, *stat3, *stat4, *stat5; int an_int; unsigned int a_uint; float a_float; double a_double; static char *my_imap[8] = { "foo", "bar", "uxxe", "blah", "gaga", "dada", "mama", "googoo" }; /* make stats database */ sdb = stat_new(); /* register stat variables */ stat_reg_int(sdb, "stat.an_int", "An integer stat variable.", &an_int, 1, NULL); stat_reg_uint(sdb, "stat.a_uint", "An unsigned integer stat variable.", &a_uint, 2, "%u (unsigned)"); stat_reg_float(sdb, "stat.a_float", "A float stat variable.", &a_float, 3, NULL); stat_reg_double(sdb, "stat.a_double", "A double stat variable.", &a_double, 4, NULL); stat_reg_formula(sdb, "stat.a_formula", "A double stat formula.", "stat.a_float / stat.a_uint", NULL); stat_reg_formula(sdb, "stat.a_formula1", "A double stat formula #1.", "2 * (stat.a_formula / (1.5 * stat.an_int))", NULL); stat_reg_formula(sdb, "stat.a_bad_formula", "A double stat formula w/error.", "stat.a_float / (stat.a_uint - 2)", NULL); stat = stat_reg_dist(sdb, "stat.a_dist", "An array distribution.", 0, 8, 1, PF_ALL, NULL, NULL, NULL); stat1 = stat_reg_dist(sdb, "stat.a_dist1", "An array distribution #1.", 0, 8, 4, PF_ALL, NULL, NULL, NULL); stat2 = stat_reg_dist(sdb, "stat.a_dist2", "An array distribution #2.", 0, 8, 1, (PF_PDF|PF_CDF), NULL, NULL, NULL); stat3 = stat_reg_dist(sdb, "stat.a_dist3", "An array distribution #3.", 0, 8, 1, PF_ALL, NULL, my_imap, NULL); stat4 = stat_reg_sdist(sdb, "stat.a_sdist", "A sparse array distribution.", 0, PF_ALL, NULL, NULL); stat5 = stat_reg_sdist(sdb, "stat.a_sdist1", "A sparse array distribution #1.", 0, PF_ALL, "0x%08lx %10lu %6.2f %6.2f", NULL); /* print initial stats */ fprintf(stdout, "** Initial stats...\n"); stat_print_stats(sdb, stdout); /* adjust stats */ an_int++; a_uint++; a_float *= 2; a_double *= 4; stat_add_sample(stat, 8); stat_add_sample(stat, 8); stat_add_sample(stat, 1); stat_add_sample(stat, 3); stat_add_sample(stat, 4); stat_add_sample(stat, 4); stat_add_sample(stat, 7); stat_add_sample(stat1, 32); stat_add_sample(stat1, 32); stat_add_sample(stat1, 1); stat_add_sample(stat1, 12); stat_add_sample(stat1, 17); stat_add_sample(stat1, 18); stat_add_sample(stat1, 30); stat_add_sample(stat2, 8); stat_add_sample(stat2, 8); stat_add_sample(stat2, 1); stat_add_sample(stat2, 3); stat_add_sample(stat2, 4); stat_add_sample(stat2, 4); stat_add_sample(stat2, 7); stat_add_sample(stat3, 8); stat_add_sample(stat3, 8); stat_add_sample(stat3, 1); stat_add_sample(stat3, 3); stat_add_sample(stat3, 4); stat_add_sample(stat3, 4); stat_add_sample(stat3, 7); stat_add_sample(stat4, 800); stat_add_sample(stat4, 800); stat_add_sample(stat4, 1123); stat_add_sample(stat4, 3332); stat_add_sample(stat4, 4000); stat_add_samples(stat4, 4001, 18); stat_add_sample(stat4, 7); stat_add_sample(stat5, 800); stat_add_sample(stat5, 800); stat_add_sample(stat5, 1123); stat_add_sample(stat5, 3332); stat_add_sample(stat5, 4000); stat_add_samples(stat5, 4001, 18); stat_add_sample(stat5, 7); /* print final stats */ fprintf(stdout, "** Final stats...\n"); stat_print_stats(sdb, stdout); /* all done */ stat_delete(sdb); exit(0);}#endif /* TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -