static void acc_percentile_emit(void* pvstate, char* value_field_name, char* acc_name, lrec_t* poutrec) { acc_percentile_state_t* pstate = pvstate; char* key = mlr_paste_3_strings(value_field_name, "_", acc_name); double p; (void)sscanf(acc_name, "p%lf", &p); // Assuming this was range-checked earlier on to be in [0,100]. double v = percentile_keeper_emit(pstate->ppercentile_keeper, p); char* s = mlr_alloc_string_from_double(v, MLR_GLOBALS.ofmt); lrec_put(poutrec, key, s, LREC_FREE_ENTRY_KEY|LREC_FREE_ENTRY_VALUE); }
// ---------------------------------------------------------------- static char* test_percentile_keeper() { percentile_keeper_t* ppercentile_keeper = percentile_keeper_alloc(); percentile_keeper_ingest(ppercentile_keeper, 1.0); percentile_keeper_ingest(ppercentile_keeper, 2.0); percentile_keeper_ingest(ppercentile_keeper, 3.0); percentile_keeper_ingest(ppercentile_keeper, 4.0); percentile_keeper_ingest(ppercentile_keeper, 5.0); percentile_keeper_print(ppercentile_keeper); double p, q; p = 0.0; q = percentile_keeper_emit(ppercentile_keeper, p); printf("%4.2lf -> %7.4lf\n", p, q); mu_assert_lf(q == 1.0); p = 10.0; q = percentile_keeper_emit(ppercentile_keeper, p); printf("%4.2lf -> %7.4lf\n", p, q); mu_assert_lf(q == 1.0); p = 50.0; q = percentile_keeper_emit(ppercentile_keeper, p); printf("%4.2lf -> %7.4lf\n", p, q); mu_assert_lf(q == 3.0); p = 90.0; q = percentile_keeper_emit(ppercentile_keeper, p); printf("%4.2lf -> %7.4lf\n", p, q); mu_assert_lf(q == 5.0); p = 100.0; q = percentile_keeper_emit(ppercentile_keeper, p); printf("%4.2lf -> %7.4lf\n", p, q); mu_assert_lf(q == 5.0); percentile_keeper_free(ppercentile_keeper); return NULL; }
static void stats1_percentile_emit(void* pvstate, char* value_field_name, char* stats1_acc_name, int copy_data, lrec_t* poutrec) { stats1_percentile_state_t* pstate = pvstate; double p; (void)sscanf(stats1_acc_name, "p%lf", &p); // Assuming this was range-checked earlier on to be in [0,100]. mv_t v = percentile_keeper_emit(pstate->ppercentile_keeper, p); char* s = mv_alloc_format_val(&v); // For this type, one accumulator tracks many stats1_names, but a single value_field_name. char* output_field_name = lhmss_get(pstate->poutput_field_names, stats1_acc_name); if (output_field_name == NULL) { output_field_name = mlr_paste_3_strings(value_field_name, "_", stats1_acc_name); lhmss_put(pstate->poutput_field_names, mlr_strdup_or_die(stats1_acc_name), output_field_name, FREE_ENTRY_KEY|FREE_ENTRY_VALUE); } lrec_put(poutrec, mlr_strdup_or_die(output_field_name), s, FREE_ENTRY_KEY|FREE_ENTRY_VALUE); }