mirror of
http://github.com/valkey-io/valkey
synced 2024-11-22 00:52:38 +00:00
double serialization routines implemented
This commit is contained in:
parent
2161a96527
commit
a7866db6cc
3
Makefile
3
Makefile
@ -5,9 +5,10 @@
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
ifeq ($(uname_S),SunOS)
|
||||
CFLAGS?= -std=c99 -pedantic -O2 -Wall -W -D__EXTENSIONS__ -D_XPG6
|
||||
CCLINK?= -ldl -lnsl -lsocket
|
||||
CCLINK?= -ldl -lnsl -lsocket -lm
|
||||
else
|
||||
CFLAGS?= -std=c99 -pedantic -O2 -Wall -W
|
||||
CCLINK?= -lm
|
||||
endif
|
||||
CCOPT= $(CFLAGS) $(CCLINK) $(ARCH)
|
||||
DEBUG?= -g -rdynamic -ggdb
|
||||
|
57
redis.c
57
redis.c
@ -57,6 +57,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "redis.h"
|
||||
#include "ae.h" /* Event driven programming library */
|
||||
@ -338,6 +339,12 @@ struct sharedObjectsStruct {
|
||||
*select5, *select6, *select7, *select8, *select9;
|
||||
} shared;
|
||||
|
||||
/* Global vars that are actally used as constants. The following double
|
||||
* values are used for double on-disk serialization, and are initialized
|
||||
* at runtime to avoid strange compiler optimizations. */
|
||||
|
||||
static double R_Zero, R_PosInf, R_NegInf, R_Nan;
|
||||
|
||||
/*================================ Prototypes =============================== */
|
||||
|
||||
static void freeStringObject(robj *o);
|
||||
@ -1021,6 +1028,12 @@ static void initServerConfig() {
|
||||
server.masterport = 6379;
|
||||
server.master = NULL;
|
||||
server.replstate = REDIS_REPL_NONE;
|
||||
|
||||
/* Double constants initialization */
|
||||
R_Zero = 0.0;
|
||||
R_PosInf = 1.0/R_Zero;
|
||||
R_NegInf = -1.0/R_Zero;
|
||||
R_Nan = R_Zero/R_Zero;
|
||||
}
|
||||
|
||||
static void initServer() {
|
||||
@ -2238,6 +2251,33 @@ static int rdbSaveStringObject(FILE *fp, robj *obj) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Save a double value. Doubles are saved as strings prefixed by an unsigned
|
||||
* 8 bit integer specifing the length of the representation.
|
||||
* This 8 bit integer has special values in order to specify the following
|
||||
* conditions:
|
||||
* 253: not a number
|
||||
* 254: + inf
|
||||
* 255: - inf
|
||||
*/
|
||||
static int rdbSaveDoubleValue(FILE *fp, double val) {
|
||||
unsigned char buf[128];
|
||||
int len;
|
||||
|
||||
if (isnan(val)) {
|
||||
buf[0] = 253;
|
||||
len = 1;
|
||||
} else if (!isfinite(val)) {
|
||||
len = 1;
|
||||
buf[0] = (val < 0) ? 255 : 254;
|
||||
} else {
|
||||
snprintf((char*)buf+1,sizeof(buf)-1,"%.16g",val);
|
||||
buf[0] = strlen((char*)buf);
|
||||
len = buf[0]+1;
|
||||
}
|
||||
if (fwrite(buf,len,1,fp) == 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success */
|
||||
static int rdbSave(char *filename) {
|
||||
dictIterator *di = NULL;
|
||||
@ -2500,6 +2540,23 @@ static robj *rdbLoadStringObject(FILE*fp, int rdbver) {
|
||||
return tryObjectSharing(createObject(REDIS_STRING,val));
|
||||
}
|
||||
|
||||
/* For information about double serialization check rdbSaveDoubleValue() */
|
||||
static int rdbLoadDoubleValue(FILE *fp, double *val) {
|
||||
char buf[128];
|
||||
unsigned char len;
|
||||
|
||||
if (fread(&len,1,1,fp) == 0) return -1;
|
||||
switch(len) {
|
||||
case 255: *val = R_NegInf; return 0;
|
||||
case 254: *val = R_PosInf; return 0;
|
||||
case 253: *val = R_Nan; return 0;
|
||||
default:
|
||||
if (fread(buf,len,1,fp) == 0) return -1;
|
||||
sscanf(buf, "%lg", val);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int rdbLoad(char *filename) {
|
||||
FILE *fp;
|
||||
robj *keyobj = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user