int rrd_xport_fn(image_desc_t *im, time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ unsigned long *col_cnt, /* number of data columns in the result */ char ***legend_v, /* legend entries */ rrd_value_t **data) /* two dimensional array containing the data */ { int i = 0, j = 0; unsigned long *ds_cnt; /* number of data sources in file */ unsigned long col, row_cnt; rrd_value_t *srcptr, *dstptr; unsigned long nof_xports = 0; unsigned long xport_counter = 0; unsigned long *ref_list; char **legend_list; int ii = 0; time_t start_tmp = 0; time_t end_tmp = 0; time_t curr_ts; unsigned long step_tmp = 1; int dataIndex; int dataMemOffset; /* pull the data from the rrd files ... */ if(data_fetch(im)==-1) return -1; /* evaluate CDEF operations ... */ if(data_calc(im)==-1) return -1; /* how many xports? */ for(i = 0; i < im->gdes_c; i++) { switch(im->gdes[i].gf) { case GF_XPORT: nof_xports++; break; default: break; } } if(nof_xports == 0) { rrd_set_error("no XPORT found, nothing to do"); return -1; } /* a list of referenced gdes */ ref_list = malloc(sizeof(int) * nof_xports); if(ref_list == NULL) return -1; /* a list to save pointers to the column's legend entry */ /* this is a return value! */ legend_list = malloc(sizeof(char *) * nof_xports); if(legend_list == NULL) { free(ref_list); return -1; } /* find referenced gdes and save their index and */ /* a pointer into their data */ for(i = 0; i < im->gdes_c; i++) { switch(im->gdes[i].gf) { case GF_XPORT: ii = im->gdes[i].vidx; if(xport_counter > nof_xports) { rrd_set_error( "too many xports: should not happen. Hmmm"); free(ref_list); free(legend_list); return -1; } ref_list[xport_counter++] = i; break; default: break; } } start_tmp = im->gdes[0].start; end_tmp = im->gdes[0].end; step_tmp = im->gdes[0].step; /* * Choose the minimum step of all the xports * Also, use the start and end times from the xport * with the smallest step. These are the data items * we will export. If we try to use the largest interval, * then we won't have data for each row in the xport. */ for(i = 0; i < nof_xports; i++) { ii = im->gdes[ref_list[i]].vidx; if (step_tmp > im->gdes[ii].step) { step_tmp = im->gdes[ii].step; start_tmp = im->gdes[ii].start; end_tmp = im->gdes[ii].end; } } *col_cnt = nof_xports; *start = start_tmp; *end = end_tmp; *step = step_tmp; row_cnt = ((*end)-(*start))/(*step) + 1; /* room for rearranged data */ /* this is a return value! */ if (((*data) = malloc((*col_cnt) * row_cnt * sizeof(rrd_value_t)))==NULL) { free(ref_list); free(legend_list); rrd_set_error("malloc xport data area"); return(-1); } dstptr = (*data); j = 0; for(i = 0; i < im->gdes_c; i++) { switch(im->gdes[i].gf) { case GF_XPORT: /* reserve room for one legend entry */ /* is FMT_LEG_LEN + 5 the correct size? */ if ((legend_list[j] = malloc(sizeof(char) * (FMT_LEG_LEN+5)))==NULL) { free(ref_list); free(legend_list); rrd_set_error("malloc xprint legend entry"); return(-1); } if (im->gdes[i].legend) /* omit bounds check, should have the same size */ strcpy (legend_list[j++], im->gdes[i].legend); else legend_list[j++][0] = '\0'; break; default: break; } } /* fill data structure */ for(curr_ts = start_tmp; curr_ts <= end_tmp; curr_ts += step_tmp) { for(i = 0; i < nof_xports; i++) { j = ref_list[i]; ii = im->gdes[j].vidx; ds_cnt = &im->gdes[ii].ds_cnt; /* * We need to make sure that each data item from each xport * appears in the row with the correct time stamp for that item * Some consolidated data (like Max, Min, Last) will only have * one data point for each n data points for a variable. */ dataIndex = ceil((double)(curr_ts - im->gdes[ii].start) / im->gdes[ii].step); dataMemOffset = dataIndex*(*ds_cnt); srcptr = im->gdes[ii].data + dataMemOffset; for(col = 0; col < (*ds_cnt); col++) { rrd_value_t newval = DNAN; newval = srcptr[col]; if (im->gdes[ii].ds_namv && im->gdes[ii].ds_nam) { if(strcmp(im->gdes[ii].ds_namv[col],im->gdes[ii].ds_nam) == 0) (*dstptr++) = newval; } else { (*dstptr++) = newval; } } } } *legend_v = legend_list; free(ref_list); return 0; }
int rrd_xport_fn( image_desc_t *im, time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ unsigned long *col_cnt, /* number of data columns in the result */ char ***legend_v, /* legend entries */ rrd_value_t **data, int dolines) { /* two dimensional array containing the data */ int i = 0, j = 0; unsigned long dst_row, row_cnt; rrd_value_t *dstptr; unsigned long xport_counter = 0; int *ref_list; long *step_list; long *step_list_ptr; char **legend_list; /* pull the data from the rrd files ... */ if (data_fetch(im) == -1) return -1; /* evaluate CDEF operations ... */ if (data_calc(im) == -1) return -1; /* how many xports or lines/AREA/STACK ? */ *col_cnt = 0; for (i = 0; i < im->gdes_c; i++) { switch (im->gdes[i].gf) { case GF_LINE: case GF_AREA: case GF_STACK: (*col_cnt)+=dolines; break; case GF_XPORT: (*col_cnt)++; break; default: break; } } if ((*col_cnt) == 0) { rrd_set_error("no XPORT found, nothing to do"); return -1; } /* a list of referenced gdes */ ref_list = (int*)malloc(sizeof(int) * (*col_cnt)); if (ref_list == NULL) return -1; /* a list to save pointers to the column's legend entry */ /* this is a return value! */ legend_list = (char**)malloc(sizeof(char *) * (*col_cnt)); if (legend_list == NULL) { free(ref_list); return -1; } /* lets find the step size we have to use for xport */ step_list = (long*)malloc(sizeof(long)*((*col_cnt)+1)); step_list_ptr = step_list; j = 0; for (i = 0; i < im->gdes_c; i++) { /* decide if we need to handle the output */ int handle=0; switch (im->gdes[i].gf) { case GF_LINE: case GF_AREA: case GF_STACK: handle=dolines; break; case GF_XPORT: handle=1; break; default: handle=0; break; } /* and now do the real work */ if (handle) { ref_list[xport_counter++] = i; *step_list_ptr = im->gdes[im->gdes[i].vidx].step; /* printf("%s:%lu\n",im->gdes[i].legend,*step_list_ptr); */ step_list_ptr++; /* reserve room for one legend entry */ if ((legend_list[j] = strdup(im->gdes[i].legend)) == NULL) { free(ref_list); *data = NULL; while (--j > -1) free(legend_list[j]); free(legend_list); free(step_list); rrd_set_error("malloc xport legend entry"); return (-1); } if (im->gdes[i].legend == 0) legend_list[j][0] = '\0'; ++j; } } *step_list_ptr=0; /* find a common step */ *step = lcd(step_list); /* printf("step: %lu\n",*step); */ free(step_list); *start = im->start - im->start % (*step); if ( im->start > *start ) { *start = *start + *step; } *end = im->end - im->end % (*step); if ( im->end > *end ) { *end = *end + *step; } /* room for rearranged data */ /* this is a return value! */ row_cnt = ((*end) - (*start)) / (*step); if (((*data) = (rrd_value_t*)malloc((*col_cnt) * row_cnt * sizeof(rrd_value_t))) == NULL) { free(ref_list); free(legend_list); rrd_set_error("malloc xport data area"); return (-1); } dstptr = (*data); /* fill data structure */ for (dst_row = 0; (int) dst_row < (int) row_cnt; dst_row++) { for (i = 0; i < (int) (*col_cnt); i++) { long vidx = im->gdes[ref_list[i]].vidx; time_t now = *start + dst_row * *step; (*dstptr++) = im->gdes[vidx].data[(unsigned long) floor((double) (now - im->gdes[vidx].start) /im->gdes[vidx].step) * im->gdes[vidx].ds_cnt + im->gdes[vidx].ds]; } } *legend_v = legend_list; free(ref_list); return 0; }
int rrd_xport_fn(image_desc_t *im, time_t *start, time_t *end, /* which time frame do you want ? * will be changed to represent reality */ unsigned long *step, /* which stepsize do you want? * will be changed to represent reality */ unsigned long *col_cnt, /* number of data columns in the result */ char ***legend_v, /* legend entries */ rrd_value_t **data) /* two dimensional array containing the data */ { int i = 0, j = 0; unsigned long *ds_cnt; /* number of data sources in file */ unsigned long col, dst_row, row_cnt; rrd_value_t *srcptr, *dstptr; unsigned long nof_xports = 0; unsigned long xport_counter = 0; unsigned long *ref_list; rrd_value_t **srcptr_list; char **legend_list; int ii = 0; time_t start_tmp = 0; time_t end_tmp = 0; unsigned long step_tmp = 1; /* pull the data from the rrd files ... */ if(data_fetch(im)==-1) return -1; /* evaluate CDEF operations ... */ if(data_calc(im)==-1) return -1; /* how many xports? */ for(i = 0; i < im->gdes_c; i++) { switch(im->gdes[i].gf) { case GF_XPORT: nof_xports++; break; default: break; } } if(nof_xports == 0) { rrd_set_error("no XPORT found, nothing to do"); return -1; } /* a list of referenced gdes */ ref_list = malloc(sizeof(int) * nof_xports); if(ref_list == NULL) return -1; /* a list to save pointers into each gdes data */ srcptr_list = malloc(sizeof(srcptr) * nof_xports); if(srcptr_list == NULL) { free(ref_list); return -1; } /* a list to save pointers to the column's legend entry */ /* this is a return value! */ legend_list = malloc(sizeof(char *) * nof_xports); if(legend_list == NULL) { free(srcptr_list); free(ref_list); return -1; } /* find referenced gdes and save their index and */ /* a pointer into their data */ for(i = 0; i < im->gdes_c; i++) { switch(im->gdes[i].gf) { case GF_XPORT: ii = im->gdes[i].vidx; if(xport_counter > nof_xports) { rrd_set_error( "too many xports: should not happen. Hmmm"); free(srcptr_list); free(ref_list); free(legend_list); return -1; } srcptr_list[xport_counter] = im->gdes[ii].data; ref_list[xport_counter++] = i; break; default: break; } } start_tmp = im->gdes[0].start; end_tmp = im->gdes[0].end; step_tmp = im->gdes[0].step; /* fill some return values */ *col_cnt = nof_xports; *start = start_tmp; *end = end_tmp; *step = step_tmp; row_cnt = ((*end)-(*start))/(*step); /* room for rearranged data */ /* this is a return value! */ if (((*data) = malloc((*col_cnt) * row_cnt * sizeof(rrd_value_t)))==NULL){ free(srcptr_list); free(ref_list); free(legend_list); rrd_set_error("malloc xport data area"); return(-1); } dstptr = (*data); j = 0; for(i = 0; i < im->gdes_c; i++) { switch(im->gdes[i].gf) { case GF_XPORT: /* reserve room for one legend entry */ /* is FMT_LEG_LEN + 5 the correct size? */ if ((legend_list[j] = malloc(sizeof(char) * (FMT_LEG_LEN+5)))==NULL) { free(srcptr_list); free(ref_list); free(*data); *data = NULL; while (--j > -1) free(legend_list[j]); free(legend_list); rrd_set_error("malloc xport legend entry"); return(-1); } if (im->gdes[i].legend) /* omit bounds check, should have the same size */ strcpy (legend_list[j++], im->gdes[i].legend); else legend_list[j++][0] = '\0'; break; default: break; } } /* fill data structure */ for(dst_row = 0; (int)dst_row < (int)row_cnt; dst_row++) { for(i = 0; i < (int)nof_xports; i++) { j = ref_list[i]; ii = im->gdes[j].vidx; ds_cnt = &im->gdes[ii].ds_cnt; srcptr = srcptr_list[i]; for(col = 0; col < (*ds_cnt); col++) { rrd_value_t newval = DNAN; newval = srcptr[col]; if (im->gdes[ii].ds_namv && im->gdes[ii].ds_nam) { if(strcmp(im->gdes[ii].ds_namv[col],im->gdes[ii].ds_nam) == 0) (*dstptr++) = newval; } else { (*dstptr++) = newval; } } srcptr_list[i] += (*ds_cnt); } } *legend_v = legend_list; free(srcptr_list); free(ref_list); return 0; }