summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 646c75d)
raw | patch | inline | side by side (parent: 646c75d)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Fri, 25 May 2007 13:12:07 +0000 (13:12 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Fri, 25 May 2007 13:12:07 +0000 (13:12 +0000) |
- fix typo in rrd_fetch where rrd_read result was checked against an
incorrect size.
- in rrd_fetch, drop rrd_head_size in favour of rrd_file->header_len
- in rrd_fetch, make the message "post fetch" unambiguous (now past vs.
post).
- change usage of param rdwr of rrd_open: allow for RRD_READONLY,
RRD_READWRITE, RRD_CREAT, RRD_READAHEAD; adjust callers accordingly:
+ rrd_resize needs CREAT
+ rrd_dump may want READAHEAD
- implement FD based I/O in rrd_open, rrd_read, rrd_write, rrd_seek.
- in rrd_update, unify write_RRA_row().
- sort | uniq the -T in .indent.pro (info_t was duplicated)
- add stub of an option to use O_DIRECT to the configury
- in Makefile.am, simplify the "indent" invocation of find:
My find may not support "-o" resp. "-or" nor braces.
Using -name "*.[ch]" works everywhere, AFAIK.
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1084 a5681a0c-68f1-0310-ab6d-d61299d08faa
incorrect size.
- in rrd_fetch, drop rrd_head_size in favour of rrd_file->header_len
- in rrd_fetch, make the message "post fetch" unambiguous (now past vs.
post).
- change usage of param rdwr of rrd_open: allow for RRD_READONLY,
RRD_READWRITE, RRD_CREAT, RRD_READAHEAD; adjust callers accordingly:
+ rrd_resize needs CREAT
+ rrd_dump may want READAHEAD
- implement FD based I/O in rrd_open, rrd_read, rrd_write, rrd_seek.
- in rrd_update, unify write_RRA_row().
- sort | uniq the -T in .indent.pro (info_t was duplicated)
- add stub of an option to use O_DIRECT to the configury
- in Makefile.am, simplify the "indent" invocation of find:
My find may not support "-o" resp. "-or" nor braces.
Using -name "*.[ch]" works everywhere, AFAIK.
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1084 a5681a0c-68f1-0310-ab6d-d61299d08faa
.indent.pro | patch | blob | history | |
Makefile.am | patch | blob | history | |
configure.ac | patch | blob | history | |
examples/perftest.pl.in | patch | blob | history | |
src/rrd_dump.c | patch | blob | history | |
src/rrd_fetch.c | patch | blob | history | |
src/rrd_open.c | patch | blob | history | |
src/rrd_resize.c | patch | blob | history | |
src/rrd_tool.h | patch | blob | history | |
src/rrd_update.c | patch | blob | history |
diff --git a/.indent.pro b/.indent.pro
index 262c7e0dc611c0da262459a1183567e1b889fb81..73401ef8b95589d70d1f8588732c66c69c253ea9 100644 (file)
--- a/.indent.pro
+++ b/.indent.pro
--case-brace-indentation0
--leave-preprocessor-space
--no-tabs
--Trrd_t
--Tinfo_t
--Ttime_t
--Toff_t
+-TFIFOqueue
+-TFnv32_t
-TTcl_Interp
--Ttm
--Tstring_arr_t
-T_ArtRgbaSVPAlphaData
--TFIFOqueue
+-Tafm_fontinfo
+-Tafm_sint16
+-Tafm_sint8
+-Tafm_uint16
+-Tafm_uint8
+-Tafm_unicode
+-Tcdp_prep_t
+-Tcgi_s
+-Tds_def_t
+-Teps_font
+-Teps_state
+-Tgfx_canvas_t
+-Tgfx_char_s
-Tgfx_color_t
-Tgfx_node_t
--Tgfx_canvas_t
--Tvar_s
--Tcgi_s
--Tinfoval
+-Tgfx_string_s
+-Tgraph_desc_t
+-Timage_desc_t
-Tinfo_t
--TFnv32_t
--Trpnp_t
+-Tinfoval
+-Tlive_head_t
+-Toff_t
+-Told_afm_fontinfo
+-Tpdf_buffer
+-Tpdf_font
+-Tpdf_point
+-Tpdf_state
+-Tpdp_prep_t
-Trpn_cdefds_t
+-Trpnp_t
-Trpnstack_t
--Tunival
--Tstat_head_t
--Tds_def_t
-Trra_def_t
--Tlive_head_t
--Tpdp_prep_t
--Tcdp_prep_t
-Trra_ptr_t
+-Trrd_file_t
-Trrd_t
+-Trrd_value_t
+-Tstat_head_t
+-Tstring_arr_t
+-Tsvg_dash
-Ttext_prop_t
+-Ttime_t
+-Ttm
+-Tunival
+-Tva_list
+-Tvar_s
-Tvdef_t
-Txlab_t
-Tygrid_scale_t
-Tylab_t
--Tgraph_desc_t
--Timage_desc_t
--Tafm_uint8
--Tafm_sint8
--Tafm_uint16
--Tafm_sint16
--Tafm_unicode
--Tafm_uint8
--Tafm_sint8
--Tafm_uint16
--Tafm_sint16
--Tafm_unicode
--Tafm_fontinfo
--Told_afm_fontinfo
--Tgfx_char_s
--Tgfx_string_s
--Tpdf_point
--Tsvg_dash
--Teps_font
--Teps_state
--Tpdf_buffer
--Tpdf_font
--Tpdf_state
--Trrd_value_t
--Trrd_file_t
--Tva_list
diff --git a/Makefile.am b/Makefile.am
index 4689aac02a076455d357b42794ba162ddb9b78e2..1c879946d82ca243fba68a7fee61e35a197d092f 100644 (file)
--- a/Makefile.am
+++ b/Makefile.am
# find . -name "*.c" -or -name "*.h" | xargs perl -0777 -n -e 'while (s/typedef\s+(?:unsigned\s+|signed\s+|unival\s+)?\S+\s+\*?([^{}\s;(]+)//){print "-T$1\n"}'
indent:
- find . -name "*.c" -or -name "*.h" | xargs indent
+ find ./ -name "*.[ch]" | xargs indent
##END##
diff --git a/configure.ac b/configure.ac
index e508eb386ad85afca863397555517357481035d1..8fa3c0075bcb9d23a0f212061aa1dcddb5ad1e91 100644 (file)
--- a/configure.ac
+++ b/configure.ac
[ --disable-mmap disable mmap in rrd_update, use seek+write instead],
[],
[enable_mmap=yes])
-
+AC_ARG_ENABLE([direct-io],
+[ --enable-direct-io enable O_DIRECT],
+[],
+[enable_direct_io=yes])
AC_ARG_ENABLE(pthread,[ --disable-pthread disable multithread support],
[],[enable_pthread=yes])
fi
+dnl if test "x$enable_direct_io" = "xyes"; then
+dnl check for working O_DIRECT
+dnl fi
+AC_SUBST([USE_DIRECT_IO])
+
CONFIGURE_PART(IEEE Math Checks)
index b10f59f5c68dc852544469797b020c8a38a45756..312ca5781795096fac0ef329fff5db65f9152530 100755 (executable)
--- a/examples/perftest.pl.in
+++ b/examples/perftest.pl.in
This test tries to cater for this. It works like this:
-1) Create 100 RRD files (and sync them to disk)
+1) Create 20k RRD files (and sync them to disk)
-2) Update the 100 RRD file three times in a row.
+2) Update the RRD files several times in a row.
We run the Update several times to see the difference
it makes in the cache.
-3) Go back to 1)
-
NOTE
use strict;
}
main;
+use strict;
+use Time::HiRes qw(time);
+use RRDs;
+use IO::File;
+use Time::HiRes qw( usleep );
+
+sub create($$){
+ my $file = shift;
+ my $time = shift;
+ my $start = time; #since we loaded HiRes
+ RRDs::create ( $file.".rrd", "-b$time", qw(
+ -s300
+ DS:in:GAUGE:400:U:U
+ DS:out:GAUGE:400:U:U
+ RRA:AVERAGE:0.5:1:600
+ RRA:AVERAGE:0.5:6:600
+ RRA:MAX:0.5:6:600
+ RRA:AVERAGE:0.5:24:600
+ RRA:MAX:0.5:24:600
+ RRA:AVERAGE:0.5:144:600
+ RRA:MAX:0.5:144:600
+ ));
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub update($$){
+ my $file = shift;
+ my $time = shift;
+ my $in = rand(1000);
+ my $out = rand(1000);
+ my $start = time;
+ my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
+# print join("",map {" $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
+ # sync updates to disk immediately
+# usleep(1) if (rand(3) <1 );
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub tune($){
+ my $file = shift;
+ my $start = time;
+ RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub infofetch($){
+ my $file = shift;
+ my $start = time;
+ my $info = RRDs::info ($file.".rrd");
+ my $error = RRDs::error;
+ die $error if $error;
+ my $lasttime = $info->{last_update} - $info->{last_update} % $info->{step};
+ my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
+ my $sum = shift;
+ my $squaresum = shift;
+ my $count = shift;
+ return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
+}
+
+sub makerrds($$$$){
+ my $count = shift;
+ my $total = shift;
+ my $list = shift;
+ my $time = shift;
+ my @files;
+ for (1..$count){
+ my $id = sprintf ("%07d",$total);
+ $id =~ s/^(.)(.)(.)(.)(.)//;
+ push @$list, "$1/$2/$3/$4/$5/$id";
+ -d "$1" or mkdir "$1";
+ -d "$1/$2" or mkdir "$1/$2";
+ -d "$1/$2/$3" or mkdir "$1/$2/$3";
+ -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
+ -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
+ push @files, $list->[$total];
+ create $list->[$total++],$time-2;
+ print STDERR ".";
+ }
+ for (@files){
+ my $fd = new IO::File("$_.rrd","r");
+ if (defined $fd) {
+ $fd->sync;
+ $fd->close;
+ } else {
+ warn "failed to sync $_\n";
+ }
+ }
+ return $count;
+}
+
+
+sub main (){
+ mkdir "db-$$" or die $!;
+ chdir "db-$$";
+
+ my $step = 200000; # number of rrds to creat for every round
+
+ my @path;
+ my $time=int(time);
+
+ my $tracksize = 0;
+ my $uppntr = 0;
+
+
+ my %squaresum = ( cr => 0, up => 0 );
+ my %sum = ( cr => 0, up => 0 );
+ my %count =( cr => 0, up => 0 );
+
+ my $printtime = time;
+ while (1) {
+ # enhance the track
+ $time += 300;
+ $tracksize += makerrds $step,$tracksize,\@path,$time;
+ # run benchmark
+ for (0..10){
+ $time += 300;
+ my $count = 0;
+ my $sum = 0;
+ my $squaresum = 0;
+ for (my $i = 0; $i<$tracksize;$i ++){
+ my $elapsed = update($path[$i],$time);
+ $sum += $elapsed;
+ $squaresum += $elapsed**2;
+ $count++;
+ };
+# for (my $i = 0; $i<$tracksize;$i ++){
+# my $fh = new IO::File "$path[$i].rrd","r";
+# if (defined $fh) {
+# $fh->sync;
+# $fh->close;
+# } else {
+# warn "failed to sync $path[$i]\n";
+# }
+# }
+ my $ups = $count/$sum;
+ my $sdv = stddev($sum,$squaresum,$count);
+ printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
+ }
+ print STDERR "\n";
+ exit ;
+ }
+}
+
+main;
diff --git a/src/rrd_dump.c b/src/rrd_dump.c
index 56ebda7622d1b34d151aa67f0ed4f8a5f3437f15..3b2a0250642b296d0364c20d3dd59c67638f27fa 100644 (file)
--- a/src/rrd_dump.c
+++ b/src/rrd_dump.c
rrd_value_t value;
struct tm tm;
- rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+ rrd_file = rrd_open(filename, &rrd, RRD_READONLY|RRD_READAHEAD);
if (rrd_file == NULL) {
rrd_free(&rrd);
return (-1);
diff --git a/src/rrd_fetch.c b/src/rrd_fetch.c
index a995fec28b9575e6a55561c9133c173710abdd0b..866bf9742ed851d6a298debe7ce17e95963ec25f 100644 (file)
--- a/src/rrd_fetch.c
+++ b/src/rrd_fetch.c
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");
fprintf(stderr, "Looking for: start %10lu end %10lu step %5lu\n",
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) =
if (rrd_seek(rrd_file, (rra_base
+ (rra_pointer
- * *ds_cnt
+ * (*ds_cnt)
* sizeof(rrd_value_t))), SEEK_SET) != 0) {
rrd_set_error("seek error in RRA");
for (i = 0; (unsigned) i < *ds_cnt; i++)
/* past the valid data area */
else if (i >= (signed) rrd.rra_def[chosen_rra].row_cnt) {
#ifdef DEBUG
- fprintf(stderr, "post fetch %li -- ", i);
+ fprintf(stderr, "past fetch %li -- ", i);
#endif
for (ii = 0; (unsigned) ii < *ds_cnt; ii++) {
*(data_ptr++) = DNAN;
if (rra_pointer >= (signed) rrd.rra_def[chosen_rra].row_cnt) {
rra_pointer -= rrd.rra_def[chosen_rra].row_cnt;
if (rrd_seek(rrd_file, (rra_base + rra_pointer
- * *ds_cnt
+ * (*ds_cnt)
* sizeof(rrd_value_t)),
SEEK_SET) != 0) {
rrd_set_error("wrap seek in RRA did fail");
}
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)) {
+ != (ssize_t) (sizeof(rrd_value_t) * (*ds_cnt))) {
rrd_set_error("fetching cdp from rra");
for (ii = 0; (unsigned) ii < *ds_cnt; ii++)
free((*ds_namv)[ii]);
/* 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_fadvise(rrd_file->fd, rrd_file->header_len, 0,
POSIX_FADV_DONTNEED)) {
rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",
filename, rrd_strerror(errno));
#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)) {
+ posix_fadvise(rrd_file->fd, rrd_file->header_len, 0,
+ POSIX_FADV_DONTNEED)) {
rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s", filename,
rrd_strerror(errno));
close(rrd_file->fd);
diff --git a/src/rrd_open.c b/src/rrd_open.c
index db4715b31c4e0e98eef5136c00cf4d76a6b62768..07ee109abc6ae6544dc2797dc621c17279a9760e 100644 (file)
--- a/src/rrd_open.c
+++ b/src/rrd_open.c
#include "unused.h"
#define MEMBLK 8192
-/* open a database file, return its header and a open filehandle */
+#ifdef HAVE_MMAP
+#define __rrd_read(dst, dst_t, cnt) \
+ (dst) = (dst_t*) (data + offset); \
+ offset += sizeof(dst_t) * (cnt)
+#else
+#define __rrd_read(dst, dst_t, cnt) \
+ if ((dst = malloc(sizeof(dst_t)*(cnt))) == NULL) { \
+ rrd_set_error(#dst " malloc"); \
+ goto out_nullify_head; \
+ } \
+ offset += read (rrd_file->fd, dst, sizeof(dst_t)*(cnt))
+#endif
+
+/* open a database file, return its header and an open filehandle */
/* positioned to the first cdp in the first rra */
rrd_file_t *rrd_open(
{
int flags = 0;
mode_t mode = S_IRUSR;
- int version, prot = PROT_READ;
- off_t offset = 0;
+ int version;
+
+#ifdef HAVE_MMAP
+ int mm_prot = PROT_READ, mm_flags = 0;
char *data;
+#endif
+ off_t offset = 0;
struct stat statb;
rrd_file_t *rrd_file = malloc(sizeof(rrd_file_t));
}
memset(rrd_file, 0, sizeof(rrd_file_t));
rrd_init(rrd);
- if (rdwr == RRD_READWRITE) {
- mode |= S_IWUSR;
- prot |= PROT_WRITE;
- } else if (rdwr == RRD_CREAT) {
- mode |= S_IWUSR;
- prot |= PROT_WRITE;
- flags |= (O_CREAT | O_TRUNC);
+#ifdef DEBUG
+ if ((rdwr & (RRD_READONLY | RRD_READWRITE)) ==
+ (RRD_READONLY | RRD_READWRITE)) {
+ /* Both READONLY and READWRITE were given, which is invalid. */
+ rrd_set_error("in read/write request mask");
+ exit(-1);
+ }
+#endif
+ if (rdwr & RRD_READONLY) {
+ flags |= O_RDONLY;
+#ifdef HAVE_MMAP
+ mm_flags = MAP_PRIVATE;
+# ifdef MAP_NORESERVE
+ mm_flags |= MAP_NORESERVE;
+# endif
+ mm_flags |= MAP_PRIVATE;
+#endif
+ } else {
+ if (rdwr & RRD_READWRITE) {
+ mode |= S_IWUSR;
+ flags |= O_RDWR;
+#ifdef HAVE_MMAP
+ mm_flags = MAP_SHARED;
+ mm_prot |= PROT_WRITE;
+#endif
+ }
+ if (rdwr & RRD_CREAT) {
+ flags |= (O_CREAT | O_TRUNC);
+ }
}
-#ifdef O_NONBLOCK
- flags |= O_NONBLOCK;
+ if (rdwr & RRD_READAHEAD) {
+#ifdef MAP_POPULATE
+ mm_flags |= MAP_POPULATE;
+#endif
+#if defined MAP_NONBLOCK && !defined USE_DIRECT_IO
+ mm_flags |= MAP_NONBLOCK; /* just populage ptes */
+#endif
+ } else {
+#ifdef USE_DIRECT_IO
+ flags |= O_DIRECT;
+#endif
+#if 0 //def O_NONBLOCK
+ flags |= O_NONBLOCK;
#endif
+ }
if ((rrd_file->fd = open(file_name, flags, mode)) < 0) {
rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
return NULL;
}
- /* ???: length = lseek(rrd_file->fd, 0, SEEK_END); */
- /* ??? locking the whole area of the file may overdo it a bit, does it? */
+ /* Better try to avoid seeks as much as possible. stat may be heavy but
+ * many concurrent seeks are even worse. */
if ((fstat(rrd_file->fd, &statb)) < 0) {
rrd_set_error("fstat '%s': %s", file_name, rrd_strerror(errno));
goto out_close;
#endif
/*
- if (rdwr == RRD_READWRITE)
+ if (rdwr & RRD_READWRITE)
{
if (setvbuf((rrd_file->fd),NULL,_IONBF,2)) {
rrd_set_error("failed to disable the stream buffer\n");
}
}
*/
- data = mmap(0, rrd_file->file_len, prot, MAP_SHARED,
+#ifdef HAVE_MMAP
+ data = mmap(0, rrd_file->file_len, mm_prot, mm_flags,
rrd_file->fd, offset);
/* lets see if the first read worked */
if (data == MAP_FAILED) {
- rrd_set_error("error mmaping file '%s'", file_name);
+ rrd_set_error("error mmaping file '%s': %s", file_name,
+ rrd_strerror(errno));
goto out_close;
}
rrd_file->file_start = data;
+#else
+#endif
#ifdef USE_MADVISE
- if (rrd == NULL) { /*XXX: currently not used! */
+ if (rdwr & RRD_COPY) { /*XXX: currently not used! */
/* We will read everything in a moment (copying) */
madvise(data, rrd_file->file_len, MADV_WILLNEED | MADV_SEQUENTIAL);
goto out_done;
madvise(data + offset, sizeof(stat_head_t), MADV_WILLNEED);
#endif
- rrd->stat_head = (stat_head_t *) (data + offset);
- offset += sizeof(stat_head_t);
+ __rrd_read(rrd->stat_head, stat_head_t,
+ 1);
/* lets do some test if we are on track ... */
if (memcmp(rrd->stat_head->cookie, RRD_COOKIE, sizeof(RRD_COOKIE)) != 0) {
madvise(data + offset, sizeof(ds_def_t) * rrd->stat_head->ds_cnt,
MADV_WILLNEED);
#endif
- rrd->ds_def = (ds_def_t *) (data + offset);
- offset += sizeof(ds_def_t) * rrd->stat_head->ds_cnt;
+ __rrd_read(rrd->ds_def, ds_def_t,
+ rrd->stat_head->ds_cnt);
#ifdef USE_MADVISE
/* the rra_def will be needed soonish, so hint accordingly */
madvise(data + offset, sizeof(rra_def_t) * rrd->stat_head->rra_cnt,
MADV_WILLNEED);
#endif
- rrd->rra_def = (rra_def_t *) (data + offset);
- offset += sizeof(rra_def_t) * rrd->stat_head->rra_cnt;
+ __rrd_read(rrd->rra_def, rra_def_t,
+ rrd->stat_head->rra_cnt);
/* handle different format for the live_head */
if (version < 3) {
rrd_set_error("live_head_t malloc");
goto out_close;
}
+#ifdef HAVE_MMAP
memmove(&rrd->live_head->last_up, data + offset, sizeof(long));
+ offset += sizeof(long);
+#else
+ offset += read(rrd_file->fd, &rrd->live_head->last_up, sizeof(long));
+#endif
rrd->live_head->last_up_usec = 0;
} else {
#ifdef USE_MADVISE
/* the live_head will be needed soonish, so hint accordingly */
madvise(data + offset, sizeof(live_head_t), MADV_WILLNEED);
#endif
- rrd->live_head = (live_head_t *) (data + offset);
- offset += sizeof(live_head_t);
+ __rrd_read(rrd->live_head, live_head_t,
+ 1);
}
-// This doesn't look like it needs madvise
- rrd->pdp_prep = (pdp_prep_t *) (data + offset);
- offset += sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt;
-
-// This could benefit from madvise()ing
- rrd->cdp_prep = (cdp_prep_t *) (data + offset);
- offset += sizeof(cdp_prep_t) *
- (rrd->stat_head->rra_cnt * rrd->stat_head->ds_cnt);
-
-// This could benefit from madvise()ing
- rrd->rra_ptr = (rra_ptr_t *) (data + offset);
- offset += sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;
+//XXX: This doesn't look like it needs madvise
+ __rrd_read(rrd->pdp_prep, pdp_prep_t,
+ rrd->stat_head->ds_cnt);
+
+//XXX: This could benefit from madvise()ing
+ __rrd_read(rrd->cdp_prep, cdp_prep_t,
+ rrd->stat_head->rra_cnt * rrd->stat_head->ds_cnt);
+
+//XXX: This could benefit from madvise()ing
+ __rrd_read(rrd->rra_ptr, rra_ptr_t,
+ rrd->stat_head->rra_cnt);
+
#ifdef USE_MADVISE
out_done:
#endif
}
/* Get current position in rrd_file. */
-off_t rrd_tell(
+inline off_t rrd_tell(
rrd_file_t *rrd_file)
{
return rrd_file->pos;
char *pos = rrd_file->file_start + rrd_file->pos;
buf = memmove(buf, pos, count);
+ rrd_file->pos += count; /* mimmic read() semantics */
return count;
#else
ssize_t ret;
ret = read(rrd_file->fd, buf, count);
//XXX: eventually add generic rrd_set_error(""); here
+ rrd_file->pos += count; /* mimmic read() semantics */
return ret;
#endif
}
/* write count bytes from buffer buf to the current position
- * rrd_file->pos of rrd_file->fd. */
+ * rrd_file->pos of rrd_file->fd.
+ * Returns the number of bytes written. */
ssize_t rrd_write(
rrd_file_t *rrd_file,
const void *buf,
new_pos = memmove(rrd_file->file_start + rrd_file->pos, buf, count);
ret = new_pos - off;
#else
- ret = write(rrd_file->fd, buf, count)
+ ret = write(rrd_file->fd, buf, count);
#endif
- return ret;
+ return ret;
}
/* flush all data pending to be written to FD. */
-void rrd_flush(
+inline void rrd_flush(
rrd_file_t *rrd_file)
{
if (fdatasync(rrd_file->fd) != 0) {
diff --git a/src/rrd_resize.c b/src/rrd_resize.c
index 1778f42448d1a527446170126bf882f8e4bef126..e29f2dd2181f8b206b9283cd760c653ffda0b0d7 100644 (file)
--- a/src/rrd_resize.c
+++ b/src/rrd_resize.c
return (-1);
}
- rrd_out_file = rrd_open(outfilename, &rrdnew, RRD_CREAT);
+ rrd_out_file = rrd_open(outfilename, &rrdnew, RRD_READWRITE|RRD_CREAT);
if (rrd_out_file == NULL) {
rrd_set_error("Can't create '%s': %s", outfilename,
rrd_strerror(errno));
diff --git a/src/rrd_tool.h b/src/rrd_tool.h
index e888c1f5c352d81c6991bec9f656dbcfde7ad011..4f43dbf7189d498d5f7ec6376f5f6a3362d626a5 100644 (file)
--- a/src/rrd_tool.h
+++ b/src/rrd_tool.h
char **buffer,
int skipfirst);
-#define RRD_READONLY 0
-#define RRD_READWRITE 1
-#define RRD_CREAT 2
+#define RRD_READONLY (1<<0)
+#define RRD_READWRITE (1<<1)
+#define RRD_CREAT (1<<2)
+#define RRD_READAHEAD (1<<3)
+#define RRD_COPY (1<<4)
enum cf_en cf_conv(
const char *string);
diff --git a/src/rrd_update.c b/src/rrd_update.c
index a34da71574cdd3f5f73061262bb8f67d37860496..7890f284d06843472c76a3a780f24016c0611cba 100644 (file)
--- a/src/rrd_update.c
+++ b/src/rrd_update.c
*****************************************************************************/
#include "rrd_tool.h"
-#include <sys/types.h>
-#include <fcntl.h>
-#ifdef HAVE_MMAP
-# include <sys/mman.h>
-#endif
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
#include <sys/locking.h>
}
}
-/* Local prototypes */
-int LockRRD(
- int in_file);
-
-#ifdef HAVE_MMAP
-info_t *write_RRA_row(
+static info_t *write_RRA_row(
+ rrd_file_t *rrd_file,
rrd_t *rrd,
unsigned long rra_idx,
unsigned long *rra_current,
unsigned short CDP_scratch_idx,
-#ifndef DEBUG
- int UNUSED(in_file),
-#else
- int in_file,
-#endif
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,
- int in_file,
- info_t *pcdp_summary,
- time_t *rra_time);
+ time_t *rra_time)
+{
+ unsigned long ds_idx, cdp_idx;
+ infoval iv;
+
+ for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
+ /* compute the cdp index */
+ cdp_idx = rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+#ifdef DEBUG
+ fprintf(stderr, " -- RRA WRITE VALUE %e, at %ld CF:%s\n",
+ rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,
+ rrd_file->pos, rrd->rra_def[rra_idx].cf_nam);
#endif
+ if (pcdp_summary != NULL) {
+ iv.u_val = rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val;
+ /* append info to the return hash */
+ pcdp_summary = info_push(pcdp_summary,
+ sprintf_alloc("[%d]RRA[%s][%lu]DS[%s]",
+ *rra_time,
+ rrd->rra_def[rra_idx].
+ cf_nam,
+ rrd->rra_def[rra_idx].
+ pdp_cnt,
+ rrd->ds_def[ds_idx].
+ ds_nam), RD_I_VAL, iv);
+ }
+ if (rrd_write
+ (rrd_file,
+ &(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
+ sizeof(rrd_value_t) * 1) != sizeof(rrd_value_t) * 1) {
+ rrd_set_error("writing rrd");
+ return 0;
+ }
+ *rra_current += sizeof(rrd_value_t);
+ }
+ return (pcdp_summary);
+}
+
int rrd_update_r(
const char *filename,
const char *tmplt,
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->fd, pcdp_summary, &rra_time,
- rrd_file->file_start);
-#else
pcdp_summary =
- write_RRA_row(&rrd, i, &rra_current, scratch_idx,
- rrd_file->fd, pcdp_summary, &rra_time);
-#endif
+ write_RRA_row(rrd_file, &rrd, i, &rra_current,
+ scratch_idx, pcdp_summary, &rra_time);
if (rrd_test_error())
break;
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->fd, pcdp_summary, &rra_time,
- rrd_file->file_start);
-#else
pcdp_summary =
- write_RRA_row(&rrd, i, &rra_current, scratch_idx,
- rrd_file->fd, pcdp_summary, &rra_time);
-#endif
+ write_RRA_row(rrd_file, &rrd, i, &rra_current,
+ scratch_idx, pcdp_summary, &rra_time);
}
if (rrd_test_error())
return (rcstat);
}
-
-
-#ifdef HAVE_MMAP
-info_t
-
-
-
-
-
-
-
-
- *write_RRA_row(
- rrd_t *rrd,
- unsigned long rra_idx,
- unsigned long *rra_current,
- unsigned short CDP_scratch_idx,
-#ifndef DEBUG
- int UNUSED(in_file),
-#else
- int in_file,
-#endif
- 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,
- int in_file,
- info_t *pcdp_summary,
- time_t *rra_time)
-#endif
-{
- unsigned long ds_idx, cdp_idx;
- infoval iv;
-
- for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
- /* compute the cdp index */
- cdp_idx = rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
-#ifdef DEBUG
- fprintf(stderr, " -- RRA WRITE VALUE %e, at %ld CF:%s\n",
- rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,
- rrd_file->pos, rrd->rra_def[rra_idx].cf_nam);
-#endif
- if (pcdp_summary != NULL) {
- iv.u_val = rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val;
- /* append info to the return hash */
- pcdp_summary = info_push(pcdp_summary,
- sprintf_alloc("[%d]RRA[%s][%lu]DS[%s]",
- *rra_time,
- rrd->rra_def[rra_idx].
- cf_nam,
- 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 (rrd_write
- (rrd_file,
- &(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
- sizeof(rrd_value_t) * 1) != sizeof(rrd_value_t) * 1) {
- rrd_set_error("writing rrd");
- return 0;
- }
-#endif
- *rra_current += sizeof(rrd_value_t);
- }
- return (pcdp_summary);
-}