updated strtold() with the faster str2ld(); fixed unit tests
Costa Tsaousis (ktsaou) committed
May 4, 2017 at 02:29 UTC
9f821248cef78512365aed6d5323d227373ae371
7 files changed
+85
-20
src/appconfig.c
+1
-1
@@ -303,7 +303,7 @@ long double appconfig_get_float(struct config *root, const char *section, const
303
s = appconfig_get(root, section, name, buffer);
304
if(!s) return value;
305
306
- return strtold(s, NULL);
306
+ return str2ld(s, NULL);
307
}
308
309
int appconfig_get_boolean(struct config *root, const char *section, const char *name, int value)
src/eval.c
+1
-1
@@ -723,7 +723,7 @@ static inline int parse_variable(const char **string, char *buffer, size_t len)
723
724
static inline int parse_constant(const char **string, calculated_number *number) {
725
char *end = NULL;
726
- calculated_number n = strtold(*string, &end);
726
+ calculated_number n = str2ld(*string, &end);
727
if(unlikely(!end || *string == end)) {
728
*number = 0;
729
return 0;
src/health_config.c
+5
-5
@@ -136,7 +136,7 @@ static inline int health_parse_duration(char *string, int *result) {
136
}
137
138
char *e = NULL;
139
- calculated_number n = strtold(string, &e);
139
+ calculated_number n = str2ld(string, &e);
140
if(e && *e) {
141
switch (*e) {
142
case 'Y':
@@ -562,7 +562,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
562
}
563
else if(hash == hash_green && !strcasecmp(key, HEALTH_GREEN_KEY)) {
564
char *e;
565
- rc->green = strtold(value, &e);
565
+ rc->green = str2ld(value, &e);
566
if(e && *e) {
567
error("Health configuration at line %zu of file '%s/%s' for alarm '%s' at key '%s' leaves this string unmatched: '%s'.",
568
line, path, filename, rc->name, key, e);
@@ -570,7 +570,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
570
}
571
else if(hash == hash_red && !strcasecmp(key, HEALTH_RED_KEY)) {
572
char *e;
573
- rc->red = strtold(value, &e);
573
+ rc->red = str2ld(value, &e);
574
if(e && *e) {
575
error("Health configuration at line %zu of file '%s/%s' for alarm '%s' at key '%s' leaves this string unmatched: '%s'.",
576
line, path, filename, rc->name, key, e);
@@ -686,7 +686,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
686
}
687
else if(hash == hash_green && !strcasecmp(key, HEALTH_GREEN_KEY)) {
688
char *e;
689
- rt->green = strtold(value, &e);
689
+ rt->green = str2ld(value, &e);
690
if(e && *e) {
691
error("Health configuration at line %zu of file '%s/%s' for template '%s' at key '%s' leaves this string unmatched: '%s'.",
692
line, path, filename, rt->name, key, e);
@@ -694,7 +694,7 @@ int health_readfile(RRDHOST *host, const char *path, const char *filename) {
694
}
695
else if(hash == hash_red && !strcasecmp(key, HEALTH_RED_KEY)) {
696
char *e;
697
- rt->red = strtold(value, &e);
697
+ rt->red = str2ld(value, &e);
698
if(e && *e) {
699
error("Health configuration at line %zu of file '%s/%s' for template '%s' at key '%s' leaves this string unmatched: '%s'.",
700
line, path, filename, rt->name, key, e);
src/inlined.h
+26
-5
@@ -156,12 +156,33 @@ static inline long double str2ld(const char *s, char **endptr) {
156
unsigned long decimal_part = 0;
157
size_t decimal_digits = 0;
158
159
- if(unlikely(*s == '-')) {
160
- s++;
161
- negative = 1;
159
+ switch(*s) {
160
+ case '-':
161
+ s++;
162
+ negative = 1;
163
+ break;
164
+
165
+ case '+':
166
+ s++;
167
+ break;
168
+
169
+ case 'n':
170
+ if(s[1] == 'a' && s[2] == 'n') {
171
+ if(endptr) *endptr = (char *)&s[3];
172
+ return NAN;
173
+ }
174
+ break;
175
+
176
+ case 'i':
177
+ if(s[1] == 'n' && s[2] == 'f') {
178
+ if(endptr) *endptr = (char *)&s[3];
179
+ return INFINITY;
180
+ }
181
+ break;
182
+
183
+ default:
184
+ break;
185
}
163
- else if(unlikely(*s == '+'))
164
- s++;
186
187
while (*s >= '0' && *s <= '9') {
188
integer_part = (integer_part * 10) + (*s - '0');
src/main.c
+4
-3
@@ -634,9 +634,10 @@ int main(int argc, char **argv) {
634
char* debug_flags_string = "debug_flags=";
635
636
if(strcmp(optarg, "unittest") == 0) {
637
- default_rrd_update_every = 1;
638
- default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
639
- if(!config_loaded) config_load(NULL, 0);
637
+ if(unit_test_str2ld()) exit(1);
638
+ //default_rrd_update_every = 1;
639
+ //default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
640
+ //if(!config_loaded) config_load(NULL, 0);
641
get_netdata_configured_variables();
642
default_rrd_update_every = 1;
643
default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
src/unit_test.c
+47
-5
@@ -17,8 +17,8 @@ int check_storage_number(calculated_number n, int debug) {
17
18
if(dcdiff < 0) dcdiff = -dcdiff;
19
20
- size_t len = print_calculated_number(buffer, d);
21
- calculated_number p = str2l(buffer);
20
+ size_t len = (size_t)print_calculated_number(buffer, d);
21
+ calculated_number p = str2ld(buffer, NULL);
22
calculated_number pdiff = n - p;
23
calculated_number pcdiff = pdiff * 100.0 / n;
24
if(pcdiff < 0) pcdiff = -pcdiff;
@@ -229,6 +229,45 @@ int unit_test_storage()
229
return r;
230
}
231
232
+int unit_test_str2ld() {
233
+ char *values[] = {
234
+ "1.234567", "-35.6", "0.00123", "23842384234234.2", ".1", "1.2e-10",
235
+ "hello", "1wrong", "nan", "inf", NULL
236
+ };
237
+
238
+ int i;
239
+ for(i = 0; values[i] ; i++) {
240
+ char *e_mine = "hello", *e_sys = "world";
241
+ long double mine = str2ld(values[i], &e_mine);
242
+ long double sys = strtold(values[i], &e_sys);
243
+
244
+ if(isnan(mine)) {
245
+ if(!isnan(sys)) {
246
+ fprintf(stderr, "Value '%s' is parsed as %Lf, but system believes it is %Lf.\n", values[i], mine, sys);
247
+ return -1;
248
+ }
249
+ }
250
+ else if(isinf(mine)) {
251
+ if(!isinf(sys)) {
252
+ fprintf(stderr, "Value '%s' is parsed as %Lf, but system believes it is %Lf.\n", values[i], mine, sys);
253
+ return -1;
254
+ }
255
+ }
256
+ else if(mine != sys && abs(mine-sys) > 0.000001) {
257
+ fprintf(stderr, "Value '%s' is parsed as %Lf, but system believes it is %Lf, delta %Lf.\n", values[i], mine, sys, sys-mine);
258
+ return -1;
259
+ }
260
+
261
+ if(e_mine != e_sys) {
262
+ fprintf(stderr, "Value '%s' is parsed correctly, but endptr is not right\n", values[i]);
263
+ return -1;
264
+ }
265
+
266
+ fprintf(stderr, "str2ld() parsed value '%s' exactly the same way with strtold(), returned %Lf vs %Lf\n", values[i], mine, sys);
267
+ }
268
+
269
+ return 0;
270
+}
271
272
// --------------------------------------------------------------------------------------------------------------------
273
@@ -244,7 +283,7 @@ struct test {
283
int update_every;
284
unsigned long long multiplier;
285
unsigned long long divisor;
247
- int algorithm;
286
+ RRD_ALGORITHM algorithm;
287
288
unsigned long feed_entries;
289
unsigned long result_entries;
@@ -916,7 +955,9 @@ int run_test(struct test *test)
955
(float)time_now / 1000000.0,
956
((calculated_number)test->feed[c].value - (calculated_number)last) * (calculated_number)test->multiplier / (calculated_number)test->divisor,
957
(((calculated_number)test->feed[c].value - (calculated_number)last) * (calculated_number)test->multiplier / (calculated_number)test->divisor) / (calculated_number)test->feed[c].microseconds * (calculated_number)1000000);
919
- rrdset_next_usec_unfiltered(st, test->feed[c].microseconds);
958
+
959
+ // rrdset_next_usec_unfiltered(st, test->feed[c].microseconds);
960
+ st->usec_since_last_update = test->feed[c].microseconds;
961
}
962
else {
963
fprintf(stderr, " > %s: feeding position %lu\n", test->name, c+1);
@@ -1125,7 +1166,8 @@ int unit_test(long delay, long shift)
1166
1167
fprintf(stderr, "\n\nLOOP = %lu, DELAY = %ld, VALUE = " COLLECTED_NUMBER_FORMAT "\n", c, delay, i);
1168
if(c) {
1128
- rrdset_next_usec_unfiltered(st, delay);
1169
+ // rrdset_next_usec_unfiltered(st, delay);
1170
+ st->usec_since_last_update = delay;
1171
}
1172
if(do_abs) rrddim_set(st, "absolute", i);
1173
if(do_inc) rrddim_set(st, "incremental", i);
src/unit_test.h
+1
@@ -4,5 +4,6 @@
4
extern int unit_test_storage(void);
5
extern int unit_test(long delay, long shift);
6
extern int run_all_mockup_tests(void);
7
+extern int unit_test_str2ld(void);
8
9
#endif /* NETDATA_UNIT_TEST_H */