don't force data out ... let cache management do this
[rrdtool.git] / src / rrd_update.c
index b114c9b..e96bc8f 100644 (file)
@@ -14,6 +14,8 @@
 #include <io.h>
 #endif
 
+#include <locale.h>
+
 #include "rrd_hw.h"
 #include "rrd_rpncalc.h"
 
@@ -135,16 +137,16 @@ info_t   *rrd_update_v(
     char     *tmplt = NULL;
     info_t   *result = NULL;
     infoval   rc;
+    struct option long_options[] = {
+        {"template", required_argument, 0, 't'},
+        {0, 0, 0, 0}
+    };
 
     rc.u_int = -1;
     optind = 0;
     opterr = 0;         /* initialize getopt */
 
     while (1) {
-        static struct option long_options[] = {
-            {"template", required_argument, 0, 't'},
-            {0, 0, 0, 0}
-        };
         int       option_index = 0;
         int       opt;
 
@@ -183,6 +185,12 @@ int rrd_update(
     int argc,
     char **argv)
 {
+    struct option long_options[] = {
+        {"template", required_argument, 0, 't'},
+        {0, 0, 0, 0}
+    };
+    int       option_index = 0;
+    int       opt;
     char     *tmplt = NULL;
     int       rc;
 
@@ -190,13 +198,6 @@ int rrd_update(
     opterr = 0;         /* initialize getopt */
 
     while (1) {
-        static struct option long_options[] = {
-            {"template", required_argument, 0, 't'},
-            {0, 0, 0, 0}
-        };
-        int       option_index = 0;
-        int       opt;
-
         opt = getopt_long(argc, argv, "t:", long_options, &option_index);
 
         if (opt == EOF)
@@ -204,7 +205,7 @@ int rrd_update(
 
         switch (opt) {
         case 't':
-            tmplt = optarg;
+            tmplt = strdup(optarg);
             break;
 
         case '?':
@@ -222,6 +223,7 @@ int rrd_update(
 
     rc = rrd_update_r(argv[optind], tmplt,
                       argc - optind - 1, (const char **) (argv + optind + 1));
+    free(tmplt);
     return rc;
 }
 
@@ -325,6 +327,8 @@ int _rrd_update(
     if (rrd_file == NULL) {
         goto err_free;
     }
+    /* We are now at the beginning of the rra's */
+    rra_current = rra_start = rra_begin = rrd_file->header_len;
 
     /* initialize time */
     version = atoi(rrd.stat_head->version);
@@ -337,26 +341,6 @@ int _rrd_update(
         current_time_usec = 0;
     }
 
-    rra_current = rra_start = rra_begin = rrd_file->header_len;
-    /* This is defined in the ANSI C standard, section 7.9.5.3:
-
-       When a file is opened with udpate mode ('+' as the second
-       or third character in the ... list of mode argument
-       variables), both input and output may be performed on the
-       associated stream.  However, ...  input may not be directly
-       followed by output without an intervening call to a file
-       positioning function, unless the input operation encounters
-       end-of-file. */
-#if 0                   //def HAVE_MMAP
-    rrd_filesize = rrd_file->file_size;
-    fseek(rrd_file->fd, 0, SEEK_END);
-    rrd_filesize = ftell(rrd_file->fd);
-    fseek(rrd_file->fd, rra_current, SEEK_SET);
-#else
-//    fseek(rrd_file->fd, 0, SEEK_CUR);
-#endif
-
-
     /* get exclusive lock to whole file.
      * lock gets removed when we close the file.
      */
@@ -435,26 +419,6 @@ int _rrd_update(
         rrd_set_error("allocating pdp_new ...");
         goto err_free_tmpl_idx;
     }
-#if 0                   //def HAVE_MMAP
-    rrd_mmaped_file = mmap(0,
-                           rrd_file->file_len,
-                           PROT_READ | PROT_WRITE,
-                           MAP_SHARED, fileno(in_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);
-        rrd_close(rrd_file);
-        return (-1);
-    }
-#ifdef USE_MADVISE
-    /* when we use mmaping we tell the kernel the mmap equivalent
-       of POSIX_FADV_RANDOM */
-    madvise(rrd_mmaped_file, rrd_filesize, POSIX_MADV_RANDOM);
-#endif
-#endif
     /* loop through the arguments. */
     for (arg_i = 0; arg_i < argc; arg_i++) {
         char     *stepper = strdup(argv[arg_i]);
@@ -471,7 +435,8 @@ int _rrd_update(
         }
         /* initialize all ds input to unknown except the first one
            which has always got to be set */
-        memset(updvals + 1, 'U', rrd.stat_head->ds_cnt);
+        for (ii = 1; ii <= rrd.stat_head->ds_cnt; ii++)
+            updvals[ii] = "U";
         updvals[0] = stepper;
         /* separate all ds elements; first must be examined separately
            due to alternate time syntax */
@@ -537,8 +502,10 @@ int _rrd_update(
             current_time_usec = tmp_time.tv_usec;
         } else {
             double    tmp;
-
+            char    *old_locale;
+            old_locale = setlocale(LC_NUMERIC,"C");
             tmp = strtod(updvals[0], 0);
+            setlocale(LC_NUMERIC,old_locale);
             current_time = floor(tmp);
             current_time_usec =
                 (long) ((tmp - (double) current_time) * 1000000.0);
@@ -558,7 +525,6 @@ int _rrd_update(
             break;
         }
 
-
         /* seek to the beginning of the rra's */
         if (rra_current != rra_begin) {
 #ifndef HAVE_MMAP
@@ -631,6 +597,7 @@ int _rrd_update(
                 (dst_idx != DST_CDEF) &&
                 rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt >= interval) {
                 double    rate = DNAN;
+                char    *old_locale;
 
                 /* the data source type defines how to process the data */
                 /* pdp_new contains rate * time ... eg the bytes
@@ -674,8 +641,10 @@ int _rrd_update(
                     }
                     break;
                 case DST_ABSOLUTE:
+                    old_locale = setlocale(LC_NUMERIC,"C");
                     errno = 0;
                     pdp_new[i] = strtod(updvals[i + 1], &endptr);
+                    setlocale(LC_NUMERIC,old_locale);
                     if (errno > 0) {
                         rrd_set_error("converting '%s' to float: %s",
                                       updvals[i + 1], rrd_strerror(errno));
@@ -691,7 +660,9 @@ int _rrd_update(
                     break;
                 case DST_GAUGE:
                     errno = 0;
+                    old_locale = setlocale(LC_NUMERIC,"C");
                     pdp_new[i] = strtod(updvals[i + 1], &endptr) * interval;
+                    setlocale(LC_NUMERIC,old_locale);
                     if (errno > 0) {
                         rrd_set_error("converting '%s' to float: %s",
                                       updvals[i + 1], rrd_strerror(errno));
@@ -1236,6 +1207,7 @@ int _rrd_update(
                                     u_val = seasonal_coef[ii];
                                 break;
                             case CF_HWPREDICT:
+                            case CF_MHWPREDICT:
                                 /* need to update the null_count and last_null_count.
                                  * even do this for non-DNAN pdp_temp because the
                                  * algorithm is not learning from batch updates. */
@@ -1334,12 +1306,10 @@ int _rrd_update(
                     (rrd.stat_head->ds_cnt) * (rrd.rra_ptr[i].cur_row) *
                     sizeof(rrd_value_t);
                 if (rra_pos_tmp != rra_current) {
-#ifndef HAVE_MMAP
                     if (rrd_seek(rrd_file, rra_pos_tmp, SEEK_SET) != 0) {
                         rrd_set_error("seek error in rrd");
                         break;
                     }
-#endif
                     rra_current = rra_pos_tmp;
                 }
 #ifdef DEBUG
@@ -1421,11 +1391,7 @@ int _rrd_update(
         free(rra_step_cnt);
     rpnstack_free(&rpnstack);
 
-#if 0                   //def HAVE_MMAP
-    if (munmap(rrd_file->file_start, rrd_file->file_len) == -1) {
-        rrd_set_error("error writing(unmapping) file: %s", filename);
-    }
-#else
+#if 0
     //rrd_flush(rrd_file);    //XXX: really needed?
 #endif
     /* if we got here and if there is an error and if the file has not been
@@ -1444,7 +1410,9 @@ int _rrd_update(
         rrd_set_error("seek rrd for live header writeback");
         goto err_free_pdp_new;
     }
-
+    /* for mmap, we did already write to the underlying mapping, so we do
+       not need to write again.  */
+#ifndef HAVE_MMAP
     if (version >= 3) {
         if (rrd_write(rrd_file, rrd.live_head,
                       sizeof(live_head_t) * 1) != sizeof(live_head_t) * 1) {
@@ -1483,19 +1451,8 @@ int _rrd_update(
         rrd_set_error("rrd_write rra_ptr to rrd");
         goto err_free_pdp_new;
     }
-#ifdef HAVE_POSIX_FADVISExxx
-
-    /* with update we have write ops, so they will probably not be done by now, this means
-       the buffers will not get freed. But calling this for the whole file - header
-       will let the data off the hook as soon as it is written when if it is from a previous
-       update cycle. Calling fdsync to force things is much too hard here. */
-
-    if (0 != posix_fadvise(rrd_file->fd, rra_begin, 0, POSIX_FADV_DONTNEED)) {
-        rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s", filename,
-                      rrd_strerror(errno));
-        goto err_free_pdp_new;
-    }
 #endif
+
     /* rrd_flush(rrd_file); */
 
     /* calling the smoothing code here guarantees at most
@@ -1519,17 +1476,9 @@ int _rrd_update(
             rra_start += rrd.rra_def[i].row_cnt
                 * rrd.stat_head->ds_cnt * sizeof(rrd_value_t);
         }
-#ifdef HAVE_POSIX_FADVISExxx
-        /* same procedure as above ... */
-        if (0 !=
-            posix_fadvise(rrd_file->fd, rra_begin, 0, POSIX_FADV_DONTNEED)) {
-            rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s", filename,
-                          rrd_strerror(errno));
-            goto err_free_pdp_new;
-        }
-#endif
     }
 
+/*    rrd_dontneed(rrd_file,&rrd); */
     rrd_free(&rrd);
     rrd_close(rrd_file);