[rrd-developers] modified reduce_data()
Alex van den Bogaerdt
alex at slot.hollandcasino.nl
Sun Feb 4 19:04:37 MET 2001
Hi,
I spent quite some time on RRDtool now and I am more and more
capable of modifying the source.
While I was doing so, I found a bug in reduce_data() or at least
I think it is one. Anyway, I completely rewrote it and the
resulting function is included next. I didn't write it as a
patch, just edit rrd_graph.c and insert it. Rename the original
function to orig_reduce_data() or so :)
One question/problem remains: shouldn't the xff factor be used
in this function ?!?
Please try the new function and let me know if anything is
wrong with it.
Thanks,
Alex
void
reduce_data(
enum cf_en cf, /* which consolidation function ?*/
unsigned long cur_step, /* step the data currently is in */
time_t *start, /* start, end and step as requested ... */
time_t *end, /* ... by the application will be ... */
unsigned long *step, /* ... adjusted to represent reality */
unsigned long *ds_cnt, /* number of data sources in file */
rrd_value_t **data) /* two dimensional array containing the data */
{
int i,reduce_factor = ceil((double)(*step) / (double)cur_step);
unsigned long col,dst_row,row_cnt,start_offset,end_offset,skiprows=0;
rrd_value_t *srcptr,*dstptr;
(*step) = cur_step*reduce_factor; /* set new step size for reduced data */
dstptr = *data;
srcptr = *data;
/* We were given one extra row at the beginning of the interval.
** We also need to return one extra row. The extra interval is
** the one defined by the start time in both cases. It is not
** used when graphing but maybe we can use it while reducing the
** data.
*/
row_cnt = ((*end)-(*start))/cur_step +1;
/* alter start and end so that they are multiples of the new steptime.
** End will be shifted towards the future and start will be shifted
** towards the past in order to include the requested interval
*/
end_offset = (*end) % (*step);
if (end_offset) end_offset = (*step)-end_offset;
start_offset = (*start) % (*step);
(*end) = (*end)+end_offset;
(*start) = (*start)-start_offset;
/* The first destination row is unknown yet it still needs
** to be present in the returned data. Skip it.
** Don't make it NaN or we might overwrite the source.
*/
dstptr += (*ds_cnt);
/* Depending on the amount of extra data needed at the
** start of the destination, three things can happen:
** -1- start_offset == 0: skip the extra source row
** -2- start_offset == cur_step: do nothing
** -3- start_offset > cur_step: skip some source rows and
** fill one destination row with NaN
*/
if (start_offset==0) {
srcptr+=(*ds_cnt);
row_cnt--;
} else if (start_offset!=cur_step) {
skiprows=((*step)-start_offset)/cur_step+1;
srcptr += ((*ds_cnt)*skiprows);
row_cnt-=skiprows;
for (col=0;col<(*ds_cnt);col++) *dstptr++=DNAN;
}
/* If we had to alter the endtime, there won't be
** enough data to fill the last row. This means
** we have to skip some rows at the end
*/
if (end_offset) {
skiprows = ((*step)-end_offset)/cur_step;
row_cnt-=skiprows;
}
/* Now combine reduce_factor intervals at a time
** into one interval for the destination.
*/
/* Sanity check: row_cnt should be multiple of reduce_factor */
if (row_cnt%reduce_factor) {
printf("SANITY CHECK: %lu rows cannot be reduced by %i \n",
row_cnt,reduce_factor);
printf("BUG in reduce_data()\n");
exit(1);
}
for (dst_row=0;row_cnt>=reduce_factor;dst_row++) {
for (col=0;col<(*ds_cnt);col++) {
rrd_value_t newval=DNAN;
unsigned long validval=0;
for (i=0;i<reduce_factor;i++) {
if (isnan(srcptr[i*(*ds_cnt)+col])) {
continue;
}
validval++;
if (isnan(newval)) newval = srcptr[i*(*ds_cnt)+col];
else {
switch (cf) {
case CF_AVERAGE:
newval += srcptr[i*(*ds_cnt)+col];
break;
case CF_MINIMUM:
newval = min (newval,srcptr[i*(*ds_cnt)+col]);
break;
case CF_MAXIMUM:
newval = max (newval,srcptr[i*(*ds_cnt)+col]);
break;
case CF_LAST:
newval = srcptr[i*(*ds_cnt)+col];
break;
}
}
}
if (validval == 0){newval = DNAN;} else{
switch (cf) {
case CF_AVERAGE:
newval /= validval;
break;
case CF_MINIMUM:
case CF_MAXIMUM:
case CF_LAST:
break;
}
}
*dstptr++=newval;
}
srcptr+=(*ds_cnt)*reduce_factor;
row_cnt-=reduce_factor;
}
/* If we had to alter the endtime, we didn't have enough
** source rows to fill the last row. Fill it with NaN.
*/
if (end_offset!=0) for (col=0;col<(*ds_cnt);col++) *dstptr++ = DNAN;
}
--
Unsubscribe mailto:rrd-developers-request at list.ee.ethz.ch?subject=unsubscribe
Help mailto:rrd-developers-request at list.ee.ethz.ch?subject=help
Archive http://www.ee.ethz.ch/~slist/rrd-developers
WebAdmin http://www.ee.ethz.ch/~slist/lsg2.cgi
More information about the rrd-developers
mailing list