static int ts_invoke_absolute (const data_set_t *ds, value_list_t *vl, /* {{{ */ ts_data_t *data, int dsrc_index) { uint64_t curr_absolute; double rate; int status; /* Required meta data */ double int_fraction; char key_int_fraction[128]; curr_absolute = (uint64_t) vl->values[dsrc_index].absolute; ssnprintf (key_int_fraction, sizeof (key_int_fraction), "target_scale[%p,%i]:int_fraction", (void *) data, dsrc_index); int_fraction = 0.0; /* Query the meta data */ status = uc_meta_data_get_double (vl, key_int_fraction, &int_fraction); if (status != 0) int_fraction = 0.0; rate = ((double) curr_absolute) / ((double) vl->interval); /* Modify the rate. */ if (!isnan (data->factor)) rate *= data->factor; if (!isnan (data->offset)) rate += data->offset; /* Calculate the new absolute. */ int_fraction += (rate * ((double) vl->interval)); curr_absolute = (uint64_t) int_fraction; int_fraction -= ((double) curr_absolute); vl->values[dsrc_index].absolute = (absolute_t) curr_absolute; /* Update to the new absolute value */ uc_meta_data_add_double (vl, key_int_fraction, int_fraction); return (0); } /* }}} int ts_invoke_absolute */
static int ts_invoke_counter(const data_set_t *ds, value_list_t *vl, /* {{{ */ ts_data_t *data, int dsrc_index) { uint64_t curr_counter; int status; int failure; /* Required meta data */ uint64_t prev_counter; char key_prev_counter[128]; uint64_t int_counter; char key_int_counter[128]; double int_fraction; char key_int_fraction[128]; curr_counter = (uint64_t)vl->values[dsrc_index].counter; snprintf(key_prev_counter, sizeof(key_prev_counter), "target_scale[%p,%i]:prev_counter", (void *)data, dsrc_index); snprintf(key_int_counter, sizeof(key_int_counter), "target_scale[%p,%i]:int_counter", (void *)data, dsrc_index); snprintf(key_int_fraction, sizeof(key_int_fraction), "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index); prev_counter = curr_counter; int_counter = 0; int_fraction = 0.0; /* Query the meta data */ failure = 0; status = uc_meta_data_get_unsigned_int(vl, key_prev_counter, &prev_counter); if (status != 0) failure++; status = uc_meta_data_get_unsigned_int(vl, key_int_counter, &int_counter); if (status != 0) failure++; status = uc_meta_data_get_double(vl, key_int_fraction, &int_fraction); if (status != 0) failure++; if (failure == 0) { uint64_t diff; double rate; diff = (uint64_t)counter_diff(prev_counter, curr_counter); rate = ((double)diff) / CDTIME_T_TO_DOUBLE(vl->interval); /* Modify the rate. */ if (!isnan(data->factor)) rate *= data->factor; if (!isnan(data->offset)) rate += data->offset; /* Calculate the internal counter. */ int_fraction += (rate * CDTIME_T_TO_DOUBLE(vl->interval)); diff = (uint64_t)int_fraction; int_fraction -= ((double)diff); int_counter += diff; assert(int_fraction >= 0.0); assert(int_fraction < 1.0); DEBUG("Target `scale': ts_invoke_counter: %" PRIu64 " -> %g -> %" PRIu64 "(+%g)", curr_counter, rate, int_counter, int_fraction); } else /* (failure != 0) */ { int_counter = 0; int_fraction = 0.0; } vl->values[dsrc_index].counter = (counter_t)int_counter; /* Update to the new counter value */ uc_meta_data_add_unsigned_int(vl, key_prev_counter, curr_counter); uc_meta_data_add_unsigned_int(vl, key_int_counter, int_counter); uc_meta_data_add_double(vl, key_int_fraction, int_fraction); return 0; } /* }}} int ts_invoke_counter */
static int ts_invoke_derive(const data_set_t *ds, value_list_t *vl, /* {{{ */ ts_data_t *data, int dsrc_index) { int64_t curr_derive; int status; int failure; /* Required meta data */ int64_t prev_derive; char key_prev_derive[128]; int64_t int_derive; char key_int_derive[128]; double int_fraction; char key_int_fraction[128]; curr_derive = (int64_t)vl->values[dsrc_index].derive; snprintf(key_prev_derive, sizeof(key_prev_derive), "target_scale[%p,%i]:prev_derive", (void *)data, dsrc_index); snprintf(key_int_derive, sizeof(key_int_derive), "target_scale[%p,%i]:int_derive", (void *)data, dsrc_index); snprintf(key_int_fraction, sizeof(key_int_fraction), "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index); prev_derive = curr_derive; int_derive = 0; int_fraction = 0.0; /* Query the meta data */ failure = 0; status = uc_meta_data_get_signed_int(vl, key_prev_derive, &prev_derive); if (status != 0) failure++; status = uc_meta_data_get_signed_int(vl, key_int_derive, &int_derive); if (status != 0) failure++; status = uc_meta_data_get_double(vl, key_int_fraction, &int_fraction); if (status != 0) failure++; if (failure == 0) { int64_t difference; double rate; /* Calcualte the rate */ difference = curr_derive - prev_derive; rate = ((double)difference) / CDTIME_T_TO_DOUBLE(vl->interval); /* Modify the rate. */ if (!isnan(data->factor)) rate *= data->factor; if (!isnan(data->offset)) rate += data->offset; /* Calculate the internal derive. */ int_fraction += (rate * CDTIME_T_TO_DOUBLE(vl->interval)); if (int_fraction < 0.0) /* handle negative integer rounding correctly */ difference = ((int64_t)int_fraction) - 1; else difference = (int64_t)int_fraction; int_fraction -= ((double)difference); int_derive += difference; assert(int_fraction >= 0.0); assert(int_fraction < 1.0); DEBUG("Target `scale': ts_invoke_derive: %" PRIu64 " -> %g -> %" PRIu64 "(+%g)", curr_derive, rate, int_derive, int_fraction); } else /* (failure != 0) */ { int_derive = 0; int_fraction = 0.0; } vl->values[dsrc_index].derive = (derive_t)int_derive; /* Update to the new derive value */ uc_meta_data_add_signed_int(vl, key_prev_derive, curr_derive); uc_meta_data_add_signed_int(vl, key_int_derive, int_derive); uc_meta_data_add_double(vl, key_int_fraction, int_fraction); return 0; } /* }}} int ts_invoke_derive */
static int ts_invoke_counter (const data_set_t *ds, value_list_t *vl, /* {{{ */ ts_data_t *data, int dsrc_index) { uint64_t curr_counter; int status; int failure; /* Required meta data */ uint64_t prev_counter; char key_prev_counter[128]; uint64_t int_counter; char key_int_counter[128]; double int_fraction; char key_int_fraction[128]; curr_counter = (uint64_t) vl->values[dsrc_index].counter; ssnprintf (key_prev_counter, sizeof (key_prev_counter), "target_scale[%p,%i]:prev_counter", (void *) data, dsrc_index); ssnprintf (key_int_counter, sizeof (key_int_counter), "target_scale[%p,%i]:int_counter", (void *) data, dsrc_index); ssnprintf (key_int_fraction, sizeof (key_int_fraction), "target_scale[%p,%i]:int_fraction", (void *) data, dsrc_index); prev_counter = curr_counter; int_counter = 0; int_fraction = 0.0; /* Query the meta data */ failure = 0; status = uc_meta_data_get_unsigned_int (vl, key_prev_counter, &prev_counter); if (status != 0) failure++; status = uc_meta_data_get_unsigned_int (vl, key_int_counter, &int_counter); if (status != 0) failure++; status = uc_meta_data_get_double (vl, key_int_fraction, &int_fraction); if (status != 0) failure++; if (failure == 0) { uint64_t difference; double rate; /* Calcualte the rate */ if (prev_counter > curr_counter) /* => counter overflow */ { if (prev_counter <= 4294967295UL) /* 32 bit overflow */ difference = (4294967295UL - prev_counter) + curr_counter; else /* 64 bit overflow */ difference = (18446744073709551615ULL - prev_counter) + curr_counter; } else /* no overflow */ { difference = curr_counter - prev_counter; } rate = ((double) difference) / ((double) vl->interval); /* Modify the rate. */ if (!isnan (data->factor)) rate *= data->factor; if (!isnan (data->offset)) rate += data->offset; /* Calculate the internal counter. */ int_fraction += (rate * ((double) vl->interval)); difference = (uint64_t) int_fraction; int_fraction -= ((double) difference); int_counter += difference; assert (int_fraction >= 0.0); assert (int_fraction < 1.0); DEBUG ("Target `scale': ts_invoke_counter: %"PRIu64" -> %g -> %"PRIu64 "(+%g)", curr_counter, rate, int_counter, int_fraction); } else /* (failure != 0) */ { int_counter = 0; int_fraction = 0.0; } vl->values[dsrc_index].counter = (counter_t) int_counter; /* Update to the new counter value */ uc_meta_data_add_unsigned_int (vl, key_prev_counter, curr_counter); uc_meta_data_add_unsigned_int (vl, key_int_counter, int_counter); uc_meta_data_add_double (vl, key_int_fraction, int_fraction); return (0); } /* }}} int ts_invoke_counter */