Skip to content

Commit

Permalink
Consolidating all ifdefs into fast_float integration header by using …
Browse files Browse the repository at this point in the history
…static inline function as wrapper.
  • Loading branch information
parthpatel committed Nov 12, 2024
1 parent ad0f785 commit 7b642a0
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 82 deletions.
6 changes: 1 addition & 5 deletions src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,11 +846,7 @@ void debugCommand(client *c) {
}
} else if (!strcasecmp(c->argv[1]->ptr, "sleep") && c->argc == 3) {
double dtime;
#ifdef USE_FAST_FLOAT
fast_float_strtod(c->argv[2]->ptr, &dtime);
#else
dtime = strtod(c->argv[2]->ptr, NULL);
#endif
valkey_strtod(c->argv[2]->ptr, &dtime);
long long utime = dtime * 1000000;
struct timespec tv;

Expand Down
5 changes: 3 additions & 2 deletions src/fast_float/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@


CXX?=c++
# We want -O3 and -flto, so that compiler can inline the function if possible.
CXXFLAGS+=-std=c++11 -O3 -fPIC -flto -D FASTFLOAT_ALLOWS_LEADING_PLUS
# We want -O3 and -flto so that compiler can inline the function.
# Currently -flto fails 32-bit build, therefore removing it.
CXXFLAGS+=-std=c++11 -O3 -fPIC -D FASTFLOAT_ALLOWS_LEADING_PLUS

.PHONY: all clean test

Expand Down
57 changes: 37 additions & 20 deletions src/fast_float/fast_float_strtod.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,43 @@ extern "C"
{
#endif

/**
* @brief Converts a null-terminated byte string to a double using the fast_float library.
*
* This function provides a C-compatible wrapper around the fast_float library's string-to-double
* conversion functionality. It aims to offer a faster alternative to the standard strtod function.
*
* @param nptr A pointer to the null-terminated byte string to be converted.
* @param value A pointer to the double variable where the function stores converted double value.
* On success, the function stores the converted double value. On failure, it stores
* 0.0 and stores error code in errno to ERANGE or EINVAL.
*
* @return On success, returns char pointer pointing to '\0' at the end of the string.
* On failure, returns char pointer pointing to first invalid character in the string.
*
* @note This function uses the fast_float library (https://github.com/fastfloat/fast_float)
* for the actual conversion, which can be significantly faster than standard library functions.
*
* @see https://github.com/fastfloat/fast_float for more information on the underlying library.
*/
const char* fast_float_strtod(const char *str, double *value);
#ifdef USE_FAST_FLOAT

/**
* @brief Converts a null-terminated byte string to a double using the fast_float library.
*
* This function provides a C-compatible wrapper around the fast_float library's string-to-double
* conversion functionality. It aims to offer a faster alternative to the standard strtod function.
*
* @param nptr A pointer to the null-terminated byte string to be converted.
* @param value A pointer to the double variable where the function stores converted double value.
* On success, the function stores the converted double value. On failure, it stores
* 0.0 and stores error code in errno to ERANGE or EINVAL.
*
* @return On success, returns char pointer pointing to '\0' at the end of the string.
* On failure, returns char pointer pointing to first invalid character in the string.
*
* @note This function uses the fast_float library (https://github.com/fastfloat/fast_float)
* for the actual conversion, which can be significantly faster than standard library functions.
*
* @see https://github.com/fastfloat/fast_float for more information on the underlying library.
*/
const char* fast_float_strtod(const char *str, double *value);

static inline const char* valkey_strtod(const char *str, double *value) {
errno = 0;
return fast_float_strtod(str, value);
}

#else

static inline const char* valkey_strtod(const char *str, double *value) {
char* endptr;
*value = strtod(str, &endptr);
return endptr;
}

#endif

#ifdef __cplusplus
}
Expand Down
11 changes: 4 additions & 7 deletions src/fast_float/test_fast_float.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,14 @@
#include "string.h"
#include "stdio.h"
#include "errno.h"
#include "math.h"
#include "math.h"

void test1()
{
void test1() {
double value = 0;
fast_float_strtod("231.2341234", &value);
assert(value == 231.2341234);
assert(errno == 0);
value = 0;
value = 0;
fast_float_strtod("+inf", &value);
assert(isinf(value));
value = 0;
Expand All @@ -53,9 +52,7 @@ void test1()
printf("fast_float test succeeded");
}

int main()
{
int main() {
test1();
return 0;
}

6 changes: 1 addition & 5 deletions src/resp_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,7 @@ static int parseDouble(ReplyParser *parser, void *p_ctx) {
if (len <= MAX_LONG_DOUBLE_CHARS) {
memcpy(buf, proto + 1, len);
buf[len] = '\0';
#ifdef USE_FAST_FLOAT
fast_float_strtod(buf, &d);
#else
d = strtod(buf, NULL); /* We expect a valid representation. */
#endif
valkey_strtod(buf, &d); /* We expect a valid representation. */
}
parser->callbacks.double_callback(p_ctx, d, proto, parser->curr_location - proto);
return C_OK;
Expand Down
8 changes: 2 additions & 6 deletions src/sort.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,13 +482,9 @@ void sortCommandGeneric(client *c, int readonly) {
if (sortby) vector[j].u.cmpobj = getDecodedObject(byval);
} else {
if (sdsEncodedObject(byval)) {
char *eptr;
#ifdef USE_FAST_FLOAT
const char *eptr;
errno = 0;
eptr = fast_float_strtod(byval->ptr, &(vector[j].u.score));
#else
vector[j].u.score = strtod(byval->ptr, &eptr);
#endif
eptr = valkey_strtod(byval->ptr, &(vector[j].u.score));
if (eptr[0] != '\0' || errno == ERANGE || errno == EINVAL || isnan(vector[j].u.score)) {
int_conversion_error = 1;
}
Expand Down
30 changes: 5 additions & 25 deletions src/t_zset.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,39 +550,23 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) {
spec->min = (long)min->ptr;
} else {
if (((char *)min->ptr)[0] == '(') {
#ifdef USE_FAST_FLOAT
eptr = fast_float_strtod((char *)min->ptr + 1, &(spec->min));
#else
spec->min = strtod((char *)min->ptr + 1, &eptr);
#endif
eptr = valkey_strtod((char *)min->ptr + 1, &(spec->min));
if (eptr[0] != '\0' || isnan(spec->min)) return C_ERR;
spec->minex = 1;
} else {
#ifdef USE_FAST_FLOAT
eptr = fast_float_strtod((char *)min->ptr, &(spec->min));
#else
spec->min = strtod((char *)min->ptr, &eptr);
#endif
eptr = valkey_strtod((char *)min->ptr, &(spec->min));
if (eptr[0] != '\0' || isnan(spec->min)) return C_ERR;
}
}
if (max->encoding == OBJ_ENCODING_INT) {
spec->max = (long)max->ptr;
} else {
if (((char *)max->ptr)[0] == '(') {
#ifdef USE_FAST_FLOAT
eptr = fast_float_strtod((char *)max->ptr + 1, &(spec->max));
#else
spec->max = strtod((char *)max->ptr + 1, &eptr);
#endif
eptr = valkey_strtod((char *)max->ptr + 1, &(spec->max));
if (eptr[0] != '\0' || isnan(spec->max)) return C_ERR;
spec->maxex = 1;
} else {
#ifdef USE_FAST_FLOAT
eptr = fast_float_strtod((char *)max->ptr, &(spec->max));
#else
spec->max = strtod((char *)max->ptr, &eptr);
#endif
eptr = valkey_strtod((char *)max->ptr, &(spec->max));
if (eptr[0] != '\0' || isnan(spec->max)) return C_ERR;
}
}
Expand Down Expand Up @@ -777,13 +761,9 @@ double zzlStrtod(unsigned char *vstr, unsigned int vlen) {
if (vlen > sizeof(buf) - 1) vlen = sizeof(buf) - 1;
memcpy(buf, vstr, vlen);
buf[vlen] = '\0';
#ifdef USE_FAST_FLOAT
double d;
fast_float_strtod(buf, &d);
valkey_strtod(buf, &d);
return d;
#else
return strtod(buf, NULL);
#endif
}

double zzlGetScore(unsigned char *sptr) {
Expand Down
7 changes: 1 addition & 6 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,7 @@ int string2ld(const char *s, size_t slen, long double *dp) {
* representing the number are accepted. */
int string2d(const char *s, size_t slen, double *dp) {
errno = 0;
#ifdef USE_FAST_FLOAT
const char *eptr = fast_float_strtod(s, dp);
#else
char *eptr;
*dp = strtod(s, &eptr);
#endif
const char *eptr = valkey_strtod(s, dp);
if (slen == 0 || isspace(((const char *)s)[0]) || (size_t)(eptr - (char *)s) != slen ||
(errno == ERANGE && (*dp == HUGE_VAL || *dp == -HUGE_VAL || fpclassify(*dp) == FP_ZERO)) || isnan(*dp) || errno == EINVAL) {
errno = 0;
Expand Down
7 changes: 1 addition & 6 deletions src/valkey-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -2547,12 +2547,7 @@ static int parseOptions(int argc, char **argv) {
} else if (!strcmp(argv[i], "-t") && !lastarg) {
double seconds;
errno = 0;
#ifdef USE_FAST_FLOAT
const char *eptr = fast_float_strtod(argv[++i], &seconds);
#else
char *eptr;
seconds = strtod(argv[++i], &eptr);
#endif
const char *eptr = valkey_strtod(argv[++i], &seconds);
if (eptr[0] != '\0' || isnan(seconds) || seconds < 0.0 || errno == EINVAL || errno == ERANGE) {
fprintf(stderr, "Invalid connection timeout for -t.\n");
exit(1);
Expand Down

0 comments on commit 7b642a0

Please sign in to comment.