提交 7229d60d 编写于 作者: A antirez

EVALSHA implemented

上级 82c6b825
......@@ -194,7 +194,8 @@ struct redisCommand redisCommandTable[] = {
{"dump",dumpCommand,2,0,NULL,0,0,0,0,0},
{"object",objectCommand,-2,0,NULL,0,0,0,0,0},
{"client",clientCommand,-2,0,NULL,0,0,0,0,0},
{"eval",evalCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}
{"eval",evalCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0},
{"evalsha",evalShaCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}
};
/*============================ Utility functions ============================ */
......@@ -781,6 +782,8 @@ void createSharedObjects(void) {
"-ERR source and destination objects are the same\r\n"));
shared.outofrangeerr = createObject(REDIS_STRING,sdsnew(
"-ERR index out of range\r\n"));
shared.noscripterr = createObject(REDIS_STRING,sdsnew(
"-NOSCRIPT No matching script. Please use EVAL.\r\n"));
shared.loadingerr = createObject(REDIS_STRING,sdsnew(
"-LOADING Redis is loading the dataset in memory\r\n"));
shared.space = createObject(REDIS_STRING,sdsnew(" "));
......
......@@ -365,7 +365,7 @@ struct sharedObjectsStruct {
robj *crlf, *ok, *err, *emptybulk, *czero, *cone, *cnegone, *pong, *space,
*colon, *nullbulk, *nullmultibulk, *queued,
*emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr,
*outofrangeerr, *loadingerr, *plus,
*outofrangeerr, *noscripterr, *loadingerr, *plus,
*select0, *select1, *select2, *select3, *select4,
*select5, *select6, *select7, *select8, *select9,
*messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, *mbulk3,
......@@ -1217,6 +1217,7 @@ void dumpCommand(redisClient *c);
void objectCommand(redisClient *c);
void clientCommand(redisClient *c);
void evalCommand(redisClient *c);
void evalShaCommand(redisClient *c);
#if defined(__GNUC__)
void *calloc(size_t count, size_t size) __attribute__ ((deprecated));
......
......@@ -4,6 +4,7 @@
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <ctype.h>
char *redisProtocolToLuaType_Int(lua_State *lua, char *reply);
char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply);
......@@ -320,7 +321,7 @@ void luaSetGlobalArray(lua_State *lua, char *var, robj **elev, int elec) {
lua_setglobal(lua,var);
}
void evalCommand(redisClient *c) {
void evalGenericCommand(redisClient *c, int evalsha) {
lua_State *lua = server.lua;
char funcname[43];
long long numkeys;
......@@ -337,11 +338,32 @@ void evalCommand(redisClient *c) {
* defined into the Lua state */
funcname[0] = 'f';
funcname[1] = '_';
hashScript(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
if (!evalsha) {
/* Hash the code if this is an EVAL call */
hashScript(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
} else {
/* We already have the SHA if it is a EVALSHA */
int j;
char *sha = c->argv[1]->ptr;
for (j = 0; j < 40; j++)
funcname[j+2] = tolower(sha[j]);
funcname[42] = '\0';
}
lua_getglobal(lua, funcname);
if (lua_isnil(lua,1)) {
/* Function not defined... let's define it. */
sds funcdef = sdsempty();
sds funcdef;
/* Function not defined... let's define it if we have the
* body of the funciton. If this is an EVALSHA call we can just
* return an error. */
if (evalsha) {
addReply(c, shared.noscripterr);
lua_pop(lua,1); /* remove the nil from the stack */
return;
}
funcdef = sdsempty();
lua_pop(lua,1); /* remove the nil from the stack */
funcdef = sdscat(funcdef,"function ");
......@@ -402,3 +424,19 @@ void evalCommand(redisClient *c) {
luaReplyToRedisReply(c,lua);
lua_gc(lua,LUA_GCSTEP,1);
}
void evalCommand(redisClient *c) {
evalGenericCommand(c,0);
}
void evalShaCommand(redisClient *c) {
if (sdslen(c->argv[1]->ptr) != 40) {
/* We know that a match is not possible if the provided SHA is
* not the right length. So we return an error ASAP, this way
* evalGenericCommand() can be implemented without string length
* sanity check */
addReply(c, shared.noscripterr);
return;
}
evalGenericCommand(c,1);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册