mirror of
https://github.com/fluencelabs/redis
synced 2025-04-10 11:16:06 +00:00
PSYNC2: just store script bodies into RDB.
Related to #4483. As suggested by @soloestoy, we can retrieve the SHA1 from the body. Given that in the new implementation using AUX fields we ended copying around a lot to create new objects and strings, extremize such concept and trade CPU for space inside the RDB file.
This commit is contained in:
parent
28dfdca733
commit
452ad2e928
34
src/rdb.c
34
src/rdb.c
@ -950,16 +950,9 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
|
|||||||
if (rsi && dictSize(server.lua_scripts)) {
|
if (rsi && dictSize(server.lua_scripts)) {
|
||||||
di = dictGetIterator(server.lua_scripts);
|
di = dictGetIterator(server.lua_scripts);
|
||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
sds sha = dictGetKey(de);
|
|
||||||
robj *body = dictGetVal(de);
|
robj *body = dictGetVal(de);
|
||||||
/* Concatenate the SHA1 and the Lua script together. Because the
|
if (rdbSaveAuxField(rdb,"lua",3,body->ptr,sdslen(body->ptr)) == -1)
|
||||||
* SHA1 is fixed length, we will always be able to load it back
|
|
||||||
* telling apart the name from the body. */
|
|
||||||
sds combo = sdsdup(sha);
|
|
||||||
combo = sdscatlen(combo,body->ptr,sdslen(body->ptr));
|
|
||||||
if (rdbSaveAuxField(rdb,"lua",3,combo,sdslen(combo)) == -1)
|
|
||||||
goto werr;
|
goto werr;
|
||||||
sdsfree(combo);
|
|
||||||
}
|
}
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
}
|
}
|
||||||
@ -1611,31 +1604,12 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi) {
|
|||||||
} else if (!strcasecmp(auxkey->ptr,"repl-offset")) {
|
} else if (!strcasecmp(auxkey->ptr,"repl-offset")) {
|
||||||
if (rsi) rsi->repl_offset = strtoll(auxval->ptr,NULL,10);
|
if (rsi) rsi->repl_offset = strtoll(auxval->ptr,NULL,10);
|
||||||
} else if (!strcasecmp(auxkey->ptr,"lua")) {
|
} else if (!strcasecmp(auxkey->ptr,"lua")) {
|
||||||
/* Load the string combining the function name and body
|
/* Load the script back in memory. */
|
||||||
* back in memory. The format is basically:
|
if (luaCreateFunction(NULL,server.lua,NULL,auxval) == C_ERR) {
|
||||||
* <sha><lua-script-bodybody>. To load it back we need
|
|
||||||
* to create the function name as "f_<sha>" and load the
|
|
||||||
* body as a Redis string object. */
|
|
||||||
sds combo = auxval->ptr;
|
|
||||||
if (sdslen(combo) < 40) {
|
|
||||||
rdbExitReportCorruptRDB(
|
|
||||||
"Lua script stored into the RDB file has invalid "
|
|
||||||
"length < 40 bytes: '%s'", combo);
|
|
||||||
}
|
|
||||||
char funcname[42];
|
|
||||||
funcname[0] = 'f';
|
|
||||||
funcname[1] = '_';
|
|
||||||
memcpy(funcname+2,combo,40);
|
|
||||||
robj *body = createRawStringObject(combo+40,sdslen(combo)-40);
|
|
||||||
|
|
||||||
/* Register the function. */
|
|
||||||
if (luaCreateFunction(NULL,server.lua,funcname,body) == C_ERR) {
|
|
||||||
rdbExitReportCorruptRDB(
|
rdbExitReportCorruptRDB(
|
||||||
"Can't load Lua script from RDB file! "
|
"Can't load Lua script from RDB file! "
|
||||||
"Script SHA1: %.42s BODY: %s",
|
"BODY: %s", auxval->ptr);
|
||||||
combo, combo+42);
|
|
||||||
}
|
}
|
||||||
decrRefCount(body);
|
|
||||||
} else {
|
} else {
|
||||||
/* We ignore fields we don't understand, as by AUX field
|
/* We ignore fields we don't understand, as by AUX field
|
||||||
* contract. */
|
* contract. */
|
||||||
|
@ -1147,11 +1147,26 @@ int redis_math_randomseed (lua_State *L) {
|
|||||||
*
|
*
|
||||||
* f_<hex sha1 sum>
|
* f_<hex sha1 sum>
|
||||||
*
|
*
|
||||||
|
* If 'funcname' is NULL, the function name is created by the function
|
||||||
|
* on the fly doing the SHA1 of the body, this means that passing the funcname
|
||||||
|
* is just an optimization in case it's already at hand.
|
||||||
|
*
|
||||||
|
* The function increments the reference count of the 'body' object as a
|
||||||
|
* side effect of a successful call.
|
||||||
|
*
|
||||||
* On success C_OK is returned, and nothing is left on the Lua stack.
|
* On success C_OK is returned, and nothing is left on the Lua stack.
|
||||||
* On error C_ERR is returned and an appropriate error is set in the
|
* On error C_ERR is returned and an appropriate error is set in the
|
||||||
* client context. */
|
* client context. */
|
||||||
int luaCreateFunction(client *c, lua_State *lua, char *funcname, robj *body) {
|
int luaCreateFunction(client *c, lua_State *lua, char *funcname, robj *body) {
|
||||||
sds funcdef = sdsempty();
|
sds funcdef = sdsempty();
|
||||||
|
char fname[42];
|
||||||
|
|
||||||
|
if (funcname == NULL) {
|
||||||
|
fname[0] = 'f';
|
||||||
|
fname[1] = '_';
|
||||||
|
sha1hex(fname+2,body->ptr,sdslen(body->ptr));
|
||||||
|
funcname = fname;
|
||||||
|
}
|
||||||
|
|
||||||
funcdef = sdscat(funcdef,"function ");
|
funcdef = sdscat(funcdef,"function ");
|
||||||
funcdef = sdscatlen(funcdef,funcname,42);
|
funcdef = sdscatlen(funcdef,funcname,42);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user