rrd_value_t **data) /* two dimensional array containing the data */
{
long i,ii;
- FILE *in_file;
time_t cal_start,cal_end, rra_start_time,rra_end_time;
long best_full_rra=0, best_part_rra=0, chosen_rra=0, rra_pointer=0;
long best_full_step_diff=0, best_part_step_diff=0, tmp_step_diff=0, tmp_match=0, best_match=0;
int first_full = 1;
int first_part = 1;
rrd_t rrd;
+ rrd_file_t *rrd_file;
rrd_value_t *data_ptr;
unsigned long rows;
+#ifdef HAVE_POSIX_FADVISE
+ long rrd_head_size;
+#endif
#ifdef DEBUG
fprintf(stderr,"Entered rrd_fetch_fn() searching for the best match\n");
*start,*end,*step);
#endif
- if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1)
+ rrd_file = rrd_open(filename,&rrd, RRD_READONLY);
+ if (rrd_file == NULL)
return(-1);
-
+
+#ifdef HAVE_POSIX_FADVISE
+ rrd_head_size = rrd_file->header_len;
+#endif
/* when was the really last update of this file ? */
if (((*ds_namv) = (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char*)))==NULL){
rrd_set_error("malloc fetch ds_namv array");
rrd_free(&rrd);
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
rrd_set_error("malloc fetch ds_namv entry");
rrd_free(&rrd);
free(*ds_namv);
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
strncpy((*ds_namv)[i],rrd.ds_def[i].ds_nam,DS_NAM_SIZE-1);
else {
rrd_set_error("the RRD does not contain an RRA matching the chosen CF");
rrd_free(&rrd);
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
free((*ds_namv)[i]);
free(*ds_namv);
rrd_free(&rrd);
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
data_ptr=(*data);
/* find base address of rra */
- rra_base=ftell(in_file);
+ rra_base = rrd_file->header_len;
for(i=0;i<chosen_rra;i++)
rra_base += ( *ds_cnt
* rrd.rra_def[i].row_cnt
else
rra_pointer = rrd.rra_ptr[chosen_rra].cur_row+1+start_offset;
- if(fseek(in_file,(rra_base
+ if(rrd_seek(rrd_file,(rra_base
+ (rra_pointer
* *ds_cnt
* sizeof(rrd_value_t))),SEEK_SET) != 0){
rrd_free(&rrd);
free(*data);
*data = NULL;
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
* be wrapped*/
if (rra_pointer >= (signed)rrd.rra_def[chosen_rra].row_cnt) {
rra_pointer -= rrd.rra_def[chosen_rra].row_cnt;
- if(fseek(in_file,(rra_base+rra_pointer
+ if(rrd_seek(rrd_file,(rra_base+rra_pointer
* *ds_cnt
* sizeof(rrd_value_t)),SEEK_SET) != 0){
rrd_set_error("wrap seek in RRA did fail");
rrd_free(&rrd);
free(*data);
*data = NULL;
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
#ifdef DEBUG
fprintf(stderr,"wrap seek ...\n");
-#endif
+#endif
}
-
- if(fread(data_ptr,
- sizeof(rrd_value_t),
- *ds_cnt,in_file) != rrd.stat_head->ds_cnt){
+
+ if(rrd_read(rrd_file,data_ptr,
+ sizeof(rrd_value_t)* (*ds_cnt))
+ != (ssize_t)(sizeof(rrd_value_t)*(*ds_cnt)*rrd.stat_head->ds_cnt)){
rrd_set_error("fetching cdp from rra");
for (ii=0;(unsigned)ii<*ds_cnt;ii++)
free((*ds_namv)[ii]);
rrd_free(&rrd);
free(*data);
*data = NULL;
- fclose(in_file);
+ close(rrd_file->fd);
return(-1);
}
+#ifdef HAVE_POSIX_FADVISE
+ /* don't pollute the buffer cache with data read from the file. We do this while reading to
+ keep damage minimal */
+ if (0 != posix_fadvise(rrd_file->fd, rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
+ rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",filename, rrd_strerror(errno));
+ close(rrd_file->fd);
+ return(-1);
+ }
+#endif
+
#ifdef DEBUG
fprintf(stderr,"post fetch %li -- ",i);
for(ii=0;ii<*ds_cnt;ii++)
}
rrd_free(&rrd);
- fclose(in_file);
+#ifdef HAVE_POSIX_FADVISE
+ /* and just to be sure we drop everything except the header at the end */
+ if (0 != posix_fadvise(rrd_file->fd, rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
+ rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",filename, rrd_strerror(errno));
+ close(rrd_file->fd);
+ return(-1);
+ }
+#endif
+ close(rrd_file->fd);
return(0);
}