From: oetiker Date: Sun, 3 Apr 2005 09:35:52 +0000 (+0000) Subject: MMAP support for rrdtool this is suposed to speed-up uptime 4 times. X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=482e470e5a6ab434ac17a92e35d275658b6b6e2f;p=rrdtool.git MMAP support for rrdtool this is suposed to speed-up uptime 4 times. -- Radoslaw Karas git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@329 a5681a0c-68f1-0310-ab6d-d61299d08faa --- diff --git a/configure.ac b/configure.ac index 06d7ba7..516707e 100644 --- a/configure.ac +++ b/configure.ac @@ -41,6 +41,7 @@ AH_TOP([ /* realloc does not support NULL as argument */ #undef NO_NULL_REALLOC + ]) AH_BOTTOM([ @@ -169,6 +170,16 @@ dnl of the form HAVE_FUNCTION AC_CHECK_FUNCS(tzset opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday) +dnl Use mmap in rrd_update instead of seek+write +AC_ARG_ENABLE([mmap], +[ --disable-mmap disable mmap in rrd_update, use seek+write instead], +[], +[enable_mmap=yes]) + +if test "x$enable_mmap" = xyes; then + AC_FUNC_MMAP +fi + dnl HP-UX 11.00 does not have finite but does have isfinite as a macro so we need dnl actual code to check if this works AC_CHECK_FUNCS(fpclassify, , @@ -323,6 +334,7 @@ AC_SUBST(PERL) AC_SUBST(COMP_PERL) AC_SUBST(PERL_VERSION) + dnl Check for Tcl. withval="" AC_ARG_WITH(tcllib,[ --with-tcllib=DIR location of the tclConfig.sh]) diff --git a/src/rrd_update.c b/src/rrd_update.c index 583d9ac..9da2cac 100644 --- a/src/rrd_update.c +++ b/src/rrd_update.c @@ -88,6 +88,9 @@ #include "rrd_tool.h" #include #include +#ifdef HAVE_MMAP + #include +#endif #ifdef WIN32 #include @@ -142,10 +145,17 @@ static void normalize_time(struct timeval *t) /* Local prototypes */ int LockRRD(FILE *rrd_file); +#ifdef HAVE_MMAP +info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, + unsigned long *rra_current, + unsigned short CDP_scratch_idx, FILE *rrd_file, + info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file); +#else info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current, unsigned short CDP_scratch_idx, FILE *rrd_file, info_t *pcdp_summary, time_t *rra_time); +#endif int rrd_update_r(char *filename, char *template, int argc, char **argv); int _rrd_update(char *filename, char *template, int argc, char **argv, info_t*); @@ -338,6 +348,10 @@ _rrd_update(char *filename, char *template, int argc, char **argv, rpnstack_t rpnstack; /* used for COMPUTE DS */ int version; /* rrd version */ char *endptr; /* used in the conversion */ +#ifdef HAVE_MMAP + void *rrd_mmaped_file; + unsigned long rrd_filesize; +#endif rpnstack_init(&rpnstack); @@ -374,7 +388,13 @@ _rrd_update(char *filename, char *template, int argc, char **argv, followed by output without an intervening call to a file positioning function, unless the input oepration encounters end-of-file. */ +#ifdef HAVE_MMAP + fseek(rrd_file, 0, SEEK_END); + rrd_filesize = ftell(rrd_file); + fseek(rrd_file, rra_current, SEEK_SET); +#else fseek(rrd_file, 0, SEEK_CUR); +#endif /* get exclusive lock to whole file. @@ -471,6 +491,23 @@ _rrd_update(char *filename, char *template, int argc, char **argv, return(-1); } +#ifdef HAVE_MMAP + rrd_mmaped_file = mmap(0, + rrd_filesize, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fileno(rrd_file), + 0); + if (rrd_mmaped_file == MAP_FAILED) { + rrd_set_error("error mmapping file %s", filename); + free(updvals); + free(pdp_temp); + free(tmpl_idx); + rrd_free(&rrd); + fclose(rrd_file); + return(-1); + } +#endif /* loop through the arguments. */ for(arg_i=0; arg_ids_cnt)*(rrd.rra_ptr[i].cur_row)*sizeof(rrd_value_t); if(rra_pos_tmp != rra_current) { +#ifndef HAVE_MMAP if(fseek(rrd_file, rra_pos_tmp, SEEK_SET) != 0){ rrd_set_error("seek error in rrd"); break; } +#endif rra_current = rra_pos_tmp; } @@ -1229,8 +1273,13 @@ _rrd_update(char *filename, char *template, int argc, char **argv, % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step)) - ((rra_step_cnt[i]-1)*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step); } +#ifdef HAVE_MMAP + pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, + pcdp_summary, &rra_time, rrd_mmaped_file); +#else pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, pcdp_summary, &rra_time); +#endif if (rrd_test_error()) break; /* write other rows of the bulk update, if any */ @@ -1262,8 +1311,13 @@ _rrd_update(char *filename, char *template, int argc, char **argv, % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step)) - ((rra_step_cnt[i]-2)*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step); } +#ifdef HAVE_MMAP + pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, + pcdp_summary, &rra_time, rrd_mmaped_file); +#else pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, pcdp_summary, &rra_time); +#endif } if (rrd_test_error()) @@ -1287,6 +1341,11 @@ _rrd_update(char *filename, char *template, int argc, char **argv, if (rra_step_cnt != NULL) free(rra_step_cnt); rpnstack_free(&rpnstack); +#ifdef HAVE_MMAP + if (munmap(rrd_mmaped_file, rrd_filesize) == -1) { + rrd_set_error("error writing(unmapping) file: %s", filename); + } +#endif /* if we got here and if there is an error and if the file has not been * written to, then close things up and return. */ if (rrd_test_error()) { @@ -1472,10 +1531,17 @@ LockRRD(FILE *rrdfile) } +#ifdef HAVE_MMAP +info_t +*write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current, + unsigned short CDP_scratch_idx, FILE *rrd_file, + info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file) +#else info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current, unsigned short CDP_scratch_idx, FILE *rrd_file, info_t *pcdp_summary, time_t *rra_time) +#endif { unsigned long ds_idx, cdp_idx; infoval iv; @@ -1499,12 +1565,18 @@ info_t rrd->rra_def[rra_idx].pdp_cnt, rrd->ds_def[ds_idx].ds_nam), RD_I_VAL, iv); } +#ifdef HAVE_MMAP + memcpy((char *)rrd_mmaped_file + *rra_current, + &(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val), + sizeof(rrd_value_t)); +#else if(fwrite(&(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val), sizeof(rrd_value_t),1,rrd_file) != 1) { rrd_set_error("writing rrd"); return 0; } +#endif *rra_current += sizeof(rrd_value_t); } return (pcdp_summary);