diff --git a/src/commands.def b/src/commands.def index f8ccdf0713..ef42fb8da7 100644 --- a/src/commands.def +++ b/src/commands.def @@ -11145,7 +11145,7 @@ struct COMMAND_STRUCT redisCommandTable[] = { {MAKE_CMD("sintercard","Returns the number of members of the intersect of multiple sets.","O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.","7.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SINTERCARD_History,0,SINTERCARD_Tips,0,sinterCardCommand,-3,CMD_READONLY,ACL_CATEGORY_SET,SINTERCARD_Keyspecs,1,sintercardGetKeys,3),.args=SINTERCARD_Args}, {MAKE_CMD("sinterstore","Stores the intersect of multiple sets in a key.","O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets.","1.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SINTERSTORE_History,0,SINTERSTORE_Tips,0,sinterstoreCommand,-3,CMD_WRITE|CMD_DENYOOM,ACL_CATEGORY_SET,SINTERSTORE_Keyspecs,2,NULL,2),.args=SINTERSTORE_Args}, {MAKE_CMD("sismember","Determines whether a member belongs to a set.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SISMEMBER_History,0,SISMEMBER_Tips,0,sismemberCommand,3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_SET,SISMEMBER_Keyspecs,1,NULL,2),.args=SISMEMBER_Args}, -{MAKE_CMD("smembers","Returns all members of a set.","O(N) where N is the set cardinality.","1.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SMEMBERS_History,0,SMEMBERS_Tips,1,sinterCommand,2,CMD_READONLY,ACL_CATEGORY_SET,SMEMBERS_Keyspecs,1,NULL,1),.args=SMEMBERS_Args}, +{MAKE_CMD("smembers","Returns all members of a set.","O(N) where N is the set cardinality.","1.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SMEMBERS_History,0,SMEMBERS_Tips,1,smembersCommand,2,CMD_READONLY,ACL_CATEGORY_SET,SMEMBERS_Keyspecs,1,NULL,1),.args=SMEMBERS_Args}, {MAKE_CMD("smismember","Determines whether multiple members belong to a set.","O(N) where N is the number of elements being checked for membership","6.2.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SMISMEMBER_History,0,SMISMEMBER_Tips,0,smismemberCommand,-3,CMD_READONLY|CMD_FAST,ACL_CATEGORY_SET,SMISMEMBER_Keyspecs,1,NULL,2),.args=SMISMEMBER_Args}, {MAKE_CMD("smove","Moves a member from one set to another.","O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SMOVE_History,0,SMOVE_Tips,0,smoveCommand,4,CMD_WRITE|CMD_FAST,ACL_CATEGORY_SET,SMOVE_Keyspecs,2,NULL,3),.args=SMOVE_Args}, {MAKE_CMD("spop","Returns one or more random members from a set after removing them. Deletes the set if the last member was popped.","Without the count argument O(1), otherwise O(N) where N is the value of the passed count.","1.0.0",CMD_DOC_NONE,NULL,NULL,"set",COMMAND_GROUP_SET,SPOP_History,1,SPOP_Tips,1,spopCommand,-2,CMD_WRITE|CMD_FAST,ACL_CATEGORY_SET,SPOP_Keyspecs,1,NULL,2),.args=SPOP_Args}, diff --git a/src/commands/smembers.json b/src/commands/smembers.json index c5114089b9..8878c18c12 100644 --- a/src/commands/smembers.json +++ b/src/commands/smembers.json @@ -5,7 +5,7 @@ "group": "set", "since": "1.0.0", "arity": 2, - "function": "sinterCommand", + "function": "smembersCommand", "command_flags": [ "READONLY" ], diff --git a/src/server.h b/src/server.h index 79cbafde5a..fe2da0a4a2 100644 --- a/src/server.h +++ b/src/server.h @@ -3639,6 +3639,7 @@ void scardCommand(client *c); void spopCommand(client *c); void srandmemberCommand(client *c); void sinterCommand(client *c); +void smembersCommand(client *c); void sinterCardCommand(client *c); void sinterstoreCommand(client *c); void sunionCommand(client *c); diff --git a/src/t_set.c b/src/t_set.c index f16cde8183..1aefda0d59 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -1244,7 +1244,7 @@ int qsortCompareSetsByRevCardinality(const void *s1, const void *s2) { return 0; } -/* SINTER / SMEMBERS / SINTERSTORE / SINTERCARD +/* SINTER / SINTERSTORE / SINTERCARD * * 'cardinality_only' work for SINTERCARD, only return the cardinality * with minimum processing and memory overheads. @@ -1420,6 +1420,33 @@ void sinterCommand(client *c) { sinterGenericCommand(c, c->argv+1, c->argc-1, NULL, 0, 0); } +/* SMEMBERS key */ +void smembersCommand(client *c) { + setTypeIterator *si; + char *str; + size_t len; + int64_t intobj; + robj *setobj = lookupKeyRead(c->db, c->argv[1]); + if (checkType(c,setobj,OBJ_SET)) return; + if (!setobj) { + addReply(c, shared.emptyset[c->resp]); + return; + } + + /* Prepare the response. */ + addReplySetLen(c,setTypeSize(setobj)); + + /* Iterate through the elements of the set. */ + si = setTypeInitIterator(setobj); + while (setTypeNext(si, &str, &len, &intobj) != -1) { + if (str != NULL) + addReplyBulkCBuffer(c, str, len); + else + addReplyBulkLongLong(c, intobj); + } + setTypeReleaseIterator(si); +} + /* SINTERCARD numkeys key [key ...] [LIMIT limit] */ void sinterCardCommand(client *c) { long j;