mirror of
https://github.com/fluencelabs/redis
synced 2025-03-30 22:31:03 +00:00
MSET and MSETNX commands implemented
This commit is contained in:
parent
f1017b3fb3
commit
f6b141c57d
8
TODO
8
TODO
@ -1,4 +1,10 @@
|
|||||||
* Expiring algorithm should be adaptive, if there are a lot of keys with an expire set and many of this happen to be already expired it should be, proportionally, more aggressive.
|
Pre 1.1 todo
|
||||||
|
|
||||||
|
* For now only the last argument gets integer encoded, so make sure that: 1) every multi bulk commands implemented will have the last arg that is indeed a value, and not used otherwise. 2) to explicitly call the function to encode the object in MSET and other commands where there are multiple "values".
|
||||||
|
|
||||||
|
After 1.1 todo
|
||||||
|
|
||||||
|
* Expiring algorithm should be adaptive, if there are a lot of keys with an expire set and many of this happen to be already expired it should be, proportionally, more aggressive.
|
||||||
* Add a command to inspect the currently selected DB index
|
* Add a command to inspect the currently selected DB index
|
||||||
* Consistent hashing implemented in all the client libraries having an user base
|
* Consistent hashing implemented in all the client libraries having an user base
|
||||||
* SORT: Don't copy the list into a vector when BY argument is constant.
|
* SORT: Don't copy the list into a vector when BY argument is constant.
|
||||||
|
@ -16,6 +16,7 @@ namespace eval redis {}
|
|||||||
set ::redis::id 0
|
set ::redis::id 0
|
||||||
array set ::redis::fd {}
|
array set ::redis::fd {}
|
||||||
array set ::redis::bulkarg {}
|
array set ::redis::bulkarg {}
|
||||||
|
array set ::redis::multibulkarg {}
|
||||||
|
|
||||||
# Flag commands requiring last argument as a bulk write operation
|
# Flag commands requiring last argument as a bulk write operation
|
||||||
foreach redis_bulk_cmd {
|
foreach redis_bulk_cmd {
|
||||||
@ -23,7 +24,16 @@ foreach redis_bulk_cmd {
|
|||||||
} {
|
} {
|
||||||
set ::redis::bulkarg($redis_bulk_cmd) {}
|
set ::redis::bulkarg($redis_bulk_cmd) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Flag commands requiring last argument as a bulk write operation
|
||||||
|
foreach redis_multibulk_cmd {
|
||||||
|
mset
|
||||||
|
} {
|
||||||
|
set ::redis::multibulkarg($redis_multibulk_cmd) {}
|
||||||
|
}
|
||||||
|
|
||||||
unset redis_bulk_cmd
|
unset redis_bulk_cmd
|
||||||
|
unset redis_multibulk_cmd
|
||||||
|
|
||||||
proc redis {{server 127.0.0.1} {port 6379}} {
|
proc redis {{server 127.0.0.1} {port 6379}} {
|
||||||
set fd [socket $server $port]
|
set fd [socket $server $port]
|
||||||
@ -36,15 +46,24 @@ proc redis {{server 127.0.0.1} {port 6379}} {
|
|||||||
proc ::redis::__dispatch__ {id method args} {
|
proc ::redis::__dispatch__ {id method args} {
|
||||||
set fd $::redis::fd($id)
|
set fd $::redis::fd($id)
|
||||||
if {[info command ::redis::__method__$method] eq {}} {
|
if {[info command ::redis::__method__$method] eq {}} {
|
||||||
set cmd "$method "
|
|
||||||
if {[info exists ::redis::bulkarg($method)]} {
|
if {[info exists ::redis::bulkarg($method)]} {
|
||||||
|
set cmd "$method "
|
||||||
append cmd [join [lrange $args 0 end-1]]
|
append cmd [join [lrange $args 0 end-1]]
|
||||||
append cmd " [string length [lindex $args end]]\r\n"
|
append cmd " [string length [lindex $args end]]\r\n"
|
||||||
append cmd [lindex $args end]
|
append cmd [lindex $args end]
|
||||||
|
::redis::redis_writenl $fd $cmd
|
||||||
|
} elseif {[info exists ::redis::multibulkarg($method)]} {
|
||||||
|
set cmd "*[expr {[llength $args]}+1]\r\n"
|
||||||
|
append cmd "$[string length $method]\r\n$method\r\n"
|
||||||
|
foreach a $args {
|
||||||
|
append cmd "$[string length $a]\r\n$a\r\n"
|
||||||
|
}
|
||||||
|
::redis::redis_write $fd $cmd
|
||||||
} else {
|
} else {
|
||||||
|
set cmd "$method "
|
||||||
append cmd [join $args]
|
append cmd [join $args]
|
||||||
|
::redis::redis_writenl $fd $cmd
|
||||||
}
|
}
|
||||||
::redis::redis_writenl $fd $cmd
|
|
||||||
::redis::redis_read_reply $fd
|
::redis::redis_read_reply $fd
|
||||||
} else {
|
} else {
|
||||||
uplevel 1 [list ::redis::__method__$method $id $fd] $args
|
uplevel 1 [list ::redis::__method__$method $id $fd] $args
|
||||||
|
52
redis.c
52
redis.c
@ -399,10 +399,13 @@ static void infoCommand(redisClient *c);
|
|||||||
static void mgetCommand(redisClient *c);
|
static void mgetCommand(redisClient *c);
|
||||||
static void monitorCommand(redisClient *c);
|
static void monitorCommand(redisClient *c);
|
||||||
static void expireCommand(redisClient *c);
|
static void expireCommand(redisClient *c);
|
||||||
static void getSetCommand(redisClient *c);
|
static void getsetCommand(redisClient *c);
|
||||||
static void ttlCommand(redisClient *c);
|
static void ttlCommand(redisClient *c);
|
||||||
static void slaveofCommand(redisClient *c);
|
static void slaveofCommand(redisClient *c);
|
||||||
static void debugCommand(redisClient *c);
|
static void debugCommand(redisClient *c);
|
||||||
|
static void msetCommand(redisClient *c);
|
||||||
|
static void msetnxCommand(redisClient *c);
|
||||||
|
|
||||||
/*================================= Globals ================================= */
|
/*================================= Globals ================================= */
|
||||||
|
|
||||||
/* Global vars */
|
/* Global vars */
|
||||||
@ -441,7 +444,9 @@ static struct redisCommand cmdTable[] = {
|
|||||||
{"smembers",sinterCommand,2,REDIS_CMD_INLINE},
|
{"smembers",sinterCommand,2,REDIS_CMD_INLINE},
|
||||||
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
||||||
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
||||||
{"getset",getSetCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
|
{"getset",getsetCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
|
||||||
|
{"mset",msetCommand,-3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
|
||||||
|
{"msetnx",msetnxCommand,-3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
|
||||||
{"randomkey",randomkeyCommand,1,REDIS_CMD_INLINE},
|
{"randomkey",randomkeyCommand,1,REDIS_CMD_INLINE},
|
||||||
{"select",selectCommand,2,REDIS_CMD_INLINE},
|
{"select",selectCommand,2,REDIS_CMD_INLINE},
|
||||||
{"move",moveCommand,3,REDIS_CMD_INLINE},
|
{"move",moveCommand,3,REDIS_CMD_INLINE},
|
||||||
@ -2596,7 +2601,7 @@ static void getCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getSetCommand(redisClient *c) {
|
static void getsetCommand(redisClient *c) {
|
||||||
getCommand(c);
|
getCommand(c);
|
||||||
if (dictAdd(c->db->dict,c->argv[1],c->argv[2]) == DICT_ERR) {
|
if (dictAdd(c->db->dict,c->argv[1],c->argv[2]) == DICT_ERR) {
|
||||||
dictReplace(c->db->dict,c->argv[1],c->argv[2]);
|
dictReplace(c->db->dict,c->argv[1],c->argv[2]);
|
||||||
@ -4094,6 +4099,42 @@ static void ttlCommand(redisClient *c) {
|
|||||||
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",ttl));
|
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",ttl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msetGenericCommand(redisClient *c, int nx) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if ((c->argc % 2) == 0) {
|
||||||
|
addReplySds(c,sdsnew("-ERR wrong number of arguments\r\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Handle the NX flag. The MSETNX semantic is to return zero and don't
|
||||||
|
* set nothing at all if at least one already key exists. */
|
||||||
|
if (nx) {
|
||||||
|
for (j = 1; j < c->argc; j += 2) {
|
||||||
|
if (dictFind(c->db->dict,c->argv[j]) != NULL) {
|
||||||
|
addReply(c, shared.czero);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 1; j < c->argc; j += 2) {
|
||||||
|
dictAdd(c->db->dict,c->argv[j],c->argv[j+1]);
|
||||||
|
incrRefCount(c->argv[j]);
|
||||||
|
incrRefCount(c->argv[j+1]);
|
||||||
|
removeExpire(c->db,c->argv[j]);
|
||||||
|
}
|
||||||
|
server.dirty += (c->argc-1)/2;
|
||||||
|
addReply(c, nx ? shared.cone : shared.ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msetCommand(redisClient *c) {
|
||||||
|
msetGenericCommand(c,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msetnxCommand(redisClient *c) {
|
||||||
|
msetGenericCommand(c,1);
|
||||||
|
}
|
||||||
|
|
||||||
/* =============================== Replication ============================= */
|
/* =============================== Replication ============================= */
|
||||||
|
|
||||||
static int syncWrite(int fd, char *ptr, ssize_t size, int timeout) {
|
static int syncWrite(int fd, char *ptr, ssize_t size, int timeout) {
|
||||||
@ -4586,7 +4627,7 @@ static struct redisFunctionSym symsTable[] = {
|
|||||||
{"mgetCommand", (unsigned long)mgetCommand},
|
{"mgetCommand", (unsigned long)mgetCommand},
|
||||||
{"monitorCommand", (unsigned long)monitorCommand},
|
{"monitorCommand", (unsigned long)monitorCommand},
|
||||||
{"expireCommand", (unsigned long)expireCommand},
|
{"expireCommand", (unsigned long)expireCommand},
|
||||||
{"getSetCommand", (unsigned long)getSetCommand},
|
{"getsetCommand", (unsigned long)getsetCommand},
|
||||||
{"ttlCommand", (unsigned long)ttlCommand},
|
{"ttlCommand", (unsigned long)ttlCommand},
|
||||||
{"slaveofCommand", (unsigned long)slaveofCommand},
|
{"slaveofCommand", (unsigned long)slaveofCommand},
|
||||||
{"debugCommand", (unsigned long)debugCommand},
|
{"debugCommand", (unsigned long)debugCommand},
|
||||||
@ -4594,6 +4635,9 @@ static struct redisFunctionSym symsTable[] = {
|
|||||||
{"setupSigSegvAction", (unsigned long)setupSigSegvAction},
|
{"setupSigSegvAction", (unsigned long)setupSigSegvAction},
|
||||||
{"readQueryFromClient", (unsigned long)readQueryFromClient},
|
{"readQueryFromClient", (unsigned long)readQueryFromClient},
|
||||||
{"rdbRemoveTempFile", (unsigned long)rdbRemoveTempFile},
|
{"rdbRemoveTempFile", (unsigned long)rdbRemoveTempFile},
|
||||||
|
{"msetGenericCommand", (unsigned long)msetGenericCommand},
|
||||||
|
{"msetCommand", (unsigned long)msetCommand},
|
||||||
|
{"msetnxCommand", (unsigned long)msetnxCommand},
|
||||||
{NULL,0}
|
{NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user