summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2016-10-03 00:08:35 +0200
committerantirez <antirez@gmail.com>2016-10-03 00:08:35 +0200
commit3dc84c530063e2ebd4f975e4066dd834cd6cbe9f (patch)
treebf347bbec08097173d9b54b683fa9b940053bfa2
parenta1b1fd4f392c59c5fc194e66856e1cb8d6a4f932 (diff)
downloadredis-3dc84c530063e2ebd4f975e4066dd834cd6cbe9f.tar.gz
Modules: API to save/load single precision floating point numbers.
When double precision is not needed, to take 2x space in the serialization is not good.
-rw-r--r--src/module.c27
-rw-r--r--src/rdb.c17
-rw-r--r--src/rdb.h2
-rw-r--r--src/redismodule.h4
4 files changed, 48 insertions, 2 deletions
diff --git a/src/module.c b/src/module.c
index ab63f8b04..e7594c166 100644
--- a/src/module.c
+++ b/src/module.c
@@ -2849,6 +2849,31 @@ double RM_LoadDouble(RedisModuleIO *io) {
return value;
}
+/* In the context of the rdb_save method of a module data type, saves a float
+ * value to the RDB file. The float can be a valid number, a NaN or infinity.
+ * It is possible to load back the value with RedisModule_LoadFloat(). */
+void RM_SaveFloat(RedisModuleIO *io, float value) {
+ if (io->error) return;
+ int retval = rdbSaveBinaryFloatValue(io->rio, value);
+ if (retval == -1) {
+ io->error = 1;
+ } else {
+ io->bytes += retval;
+ }
+}
+
+/* In the context of the rdb_save method of a module data type, loads back the
+ * float value saved by RedisModule_SaveFloat(). */
+float RM_LoadFloat(RedisModuleIO *io) {
+ float value;
+ int retval = rdbLoadBinaryFloatValue(io->rio, &value);
+ if (retval == -1) {
+ moduleRDBLoadError(io);
+ return 0; /* Never reached. */
+ }
+ return value;
+}
+
/* --------------------------------------------------------------------------
* AOF API for modules data types
* -------------------------------------------------------------------------- */
@@ -3280,6 +3305,8 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(LoadStringBuffer);
REGISTER_API(SaveDouble);
REGISTER_API(LoadDouble);
+ REGISTER_API(SaveFloat);
+ REGISTER_API(LoadFloat);
REGISTER_API(EmitAOF);
REGISTER_API(Log);
REGISTER_API(LogIOError);
diff --git a/src/rdb.c b/src/rdb.c
index 5e03dbab5..252044344 100644
--- a/src/rdb.c
+++ b/src/rdb.c
@@ -567,17 +567,30 @@ int rdbLoadDoubleValue(rio *rdb, double *val) {
* Return -1 on error, the size of the serialized value on success. */
int rdbSaveBinaryDoubleValue(rio *rdb, double val) {
memrev64ifbe(&val);
- return rdbWriteRaw(rdb,&val,8);
+ return rdbWriteRaw(rdb,&val,sizeof(val));
}
/* Loads a double from RDB 8 or greater. See rdbSaveBinaryDoubleValue() for
* more info. On error -1 is returned, otherwise 0. */
int rdbLoadBinaryDoubleValue(rio *rdb, double *val) {
- if (rioRead(rdb,val,8) == 0) return -1;
+ if (rioRead(rdb,val,sizeof(*val)) == 0) return -1;
memrev64ifbe(val);
return 0;
}
+/* Like rdbSaveBinaryDoubleValue() but single precision. */
+int rdbSaveBinaryFloatValue(rio *rdb, float val) {
+ memrev32ifbe(&val);
+ return rdbWriteRaw(rdb,&val,sizeof(val));
+}
+
+/* Like rdbLoadBinaryDoubleValue() but single precision. */
+int rdbLoadBinaryFloatValue(rio *rdb, float *val) {
+ if (rioRead(rdb,val,sizeof(*val)) == 0) return -1;
+ memrev32ifbe(val);
+ return 0;
+}
+
/* Save the object type of object "o". */
int rdbSaveObjectType(rio *rdb, robj *o) {
switch (o->type) {
diff --git a/src/rdb.h b/src/rdb.h
index cd1d65392..60c52a7c1 100644
--- a/src/rdb.h
+++ b/src/rdb.h
@@ -134,6 +134,8 @@ ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len);
void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr);
int rdbSaveBinaryDoubleValue(rio *rdb, double val);
int rdbLoadBinaryDoubleValue(rio *rdb, double *val);
+int rdbSaveBinaryFloatValue(rio *rdb, float val);
+int rdbLoadBinaryFloatValue(rio *rdb, float *val);
int rdbLoadRio(rio *rdb);
#endif
diff --git a/src/redismodule.h b/src/redismodule.h
index dcc0aa1ea..346110090 100644
--- a/src/redismodule.h
+++ b/src/redismodule.h
@@ -184,6 +184,8 @@ RedisModuleString *REDISMODULE_API_FUNC(RedisModule_LoadString)(RedisModuleIO *i
char *REDISMODULE_API_FUNC(RedisModule_LoadStringBuffer)(RedisModuleIO *io, size_t *lenptr);
void REDISMODULE_API_FUNC(RedisModule_SaveDouble)(RedisModuleIO *io, double value);
double REDISMODULE_API_FUNC(RedisModule_LoadDouble)(RedisModuleIO *io);
+void REDISMODULE_API_FUNC(RedisModule_SaveFloat)(RedisModuleIO *io, float value);
+float REDISMODULE_API_FUNC(RedisModule_LoadFloat)(RedisModuleIO *io);
void REDISMODULE_API_FUNC(RedisModule_Log)(RedisModuleCtx *ctx, const char *level, const char *fmt, ...);
void REDISMODULE_API_FUNC(RedisModule_LogIOError)(RedisModuleIO *io, const char *levelstr, const char *fmt, ...);
int REDISMODULE_API_FUNC(RedisModule_StringAppendBuffer)(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len);
@@ -281,6 +283,8 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API(LoadStringBuffer);
REDISMODULE_GET_API(SaveDouble);
REDISMODULE_GET_API(LoadDouble);
+ REDISMODULE_GET_API(SaveFloat);
+ REDISMODULE_GET_API(LoadFloat);
REDISMODULE_GET_API(EmitAOF);
REDISMODULE_GET_API(Log);
REDISMODULE_GET_API(LogIOError);