Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
f4f56e1d
Commit
f4f56e1d
authored
May 17, 2009
by
antirez
Browse files
SDIFF/SDIFFSTORE implemnted unifying it with the implementation of SUNION/SUNIONSTORE
parent
1904ecc1
Changes
3
Hide whitespace changes
Inline
Side-by-side
redis-cli.c
View file @
f4f56e1d
...
@@ -83,6 +83,8 @@ static struct redisCommand cmdTable[] = {
...
@@ -83,6 +83,8 @@ static struct redisCommand cmdTable[] = {
{
"sinterstore"
,
-
3
,
REDIS_CMD_INLINE
},
{
"sinterstore"
,
-
3
,
REDIS_CMD_INLINE
},
{
"sunion"
,
-
2
,
REDIS_CMD_INLINE
},
{
"sunion"
,
-
2
,
REDIS_CMD_INLINE
},
{
"sunionstore"
,
-
3
,
REDIS_CMD_INLINE
},
{
"sunionstore"
,
-
3
,
REDIS_CMD_INLINE
},
{
"sdiff"
,
-
2
,
REDIS_CMD_INLINE
},
{
"sdiffstore"
,
-
3
,
REDIS_CMD_INLINE
},
{
"smembers"
,
2
,
REDIS_CMD_INLINE
},
{
"smembers"
,
2
,
REDIS_CMD_INLINE
},
{
"incrby"
,
3
,
REDIS_CMD_INLINE
},
{
"incrby"
,
3
,
REDIS_CMD_INLINE
},
{
"decrby"
,
3
,
REDIS_CMD_INLINE
},
{
"decrby"
,
3
,
REDIS_CMD_INLINE
},
...
...
redis.c
View file @
f4f56e1d
...
@@ -348,6 +348,8 @@ static void sinterCommand(redisClient *c);
...
@@ -348,6 +348,8 @@ static void sinterCommand(redisClient *c);
static void sinterstoreCommand(redisClient *c);
static void sinterstoreCommand(redisClient *c);
static void sunionCommand(redisClient *c);
static void sunionCommand(redisClient *c);
static void sunionstoreCommand(redisClient *c);
static void sunionstoreCommand(redisClient *c);
static void sdiffCommand(redisClient *c);
static void sdiffstoreCommand(redisClient *c);
static void syncCommand(redisClient *c);
static void syncCommand(redisClient *c);
static void flushdbCommand(redisClient *c);
static void flushdbCommand(redisClient *c);
static void flushallCommand(redisClient *c);
static void flushallCommand(redisClient *c);
...
@@ -391,6 +393,8 @@ static struct redisCommand cmdTable[] = {
...
@@ -391,6 +393,8 @@ static struct redisCommand cmdTable[] = {
{"sinterstore",sinterstoreCommand,-3,REDIS_CMD_INLINE},
{"sinterstore",sinterstoreCommand,-3,REDIS_CMD_INLINE},
{"sunion",sunionCommand,-2,REDIS_CMD_INLINE},
{"sunion",sunionCommand,-2,REDIS_CMD_INLINE},
{"sunionstore",sunionstoreCommand,-3,REDIS_CMD_INLINE},
{"sunionstore",sunionstoreCommand,-3,REDIS_CMD_INLINE},
{"sdiff",sdiffCommand,-2,REDIS_CMD_INLINE},
{"sdiffstore",sdiffstoreCommand,-3,REDIS_CMD_INLINE},
{"smembers",sinterCommand,2,REDIS_CMD_INLINE},
{"smembers",sinterCommand,2,REDIS_CMD_INLINE},
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE},
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE},
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE},
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE},
...
@@ -3057,14 +3061,17 @@ static void sinterstoreCommand(redisClient *c) {
...
@@ -3057,14 +3061,17 @@ static void sinterstoreCommand(redisClient *c) {
sinterGenericCommand(c,c->argv+2,c->argc-2,c->argv[1]);
sinterGenericCommand(c,c->argv+2,c->argc-2,c->argv[1]);
}
}
static
void
sunionGenericCommand
(
redisClient
*
c
,
robj
**
setskeys
,
int
setsnum
,
robj
*
dstkey
)
{
#define REDIS_OP_UNION 0
#define REDIS_OP_DIFF 1
static void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnum, robj *dstkey, int op) {
dict **dv = zmalloc(sizeof(dict*)*setsnum);
dict **dv = zmalloc(sizeof(dict*)*setsnum);
dictIterator *di;
dictIterator *di;
dictEntry *de;
dictEntry *de;
robj
*
lenobj
=
NULL
,
*
dstset
=
NULL
;
robj *dstset = NULL;
int j, cardinality = 0;
int j, cardinality = 0;
if
(
!
dv
)
oom
(
"sunionCommand"
);
if (!dv) oom("sunion
DiffGeneric
Command");
for (j = 0; j < setsnum; j++) {
for (j = 0; j < setsnum; j++) {
robj *setobj;
robj *setobj;
...
@@ -3093,11 +3100,7 @@ static void sunionGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
...
@@ -3093,11 +3100,7 @@ static void sunionGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
* the intersection set size, so we use a trick, append an empty object
* the intersection set size, so we use a trick, append an empty object
* to the output list and save the pointer to later modify it with the
* to the output list and save the pointer to later modify it with the
* right length */
* right length */
if
(
!
dstkey
)
{
if (dstkey) {
lenobj
=
createObject
(
REDIS_STRING
,
NULL
);
addReply
(
c
,
lenobj
);
decrRefCount
(
lenobj
);
}
else
{
/* If we have a target key where to store the resulting set
/* If we have a target key where to store the resulting set
* create this key with an empty set inside */
* create this key with an empty set inside */
deleteKey(c->db,dstkey);
deleteKey(c->db,dstkey);
...
@@ -3119,22 +3122,39 @@ static void sunionGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
...
@@ -3119,22 +3122,39 @@ static void sunionGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
/* dictAdd will not add the same element multiple times */
/* dictAdd will not add the same element multiple times */
ele = dictGetEntryKey(de);
ele = dictGetEntryKey(de);
if
(
dictAdd
(
dstset
->
ptr
,
ele
,
NULL
)
==
DICT_OK
)
{
if (op == REDIS_OP_UNION || j == 0) {
incrRefCount
(
ele
);
if (dictAdd(dstset->ptr,ele,NULL) == DICT_OK) {
if
(
!
dstkey
)
{
incrRefCount(ele);
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
"$%d
\r\n
"
,
sdslen
(
ele
->
ptr
)));
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
cardinality++;
cardinality++;
}
}
} else if (op == REDIS_OP_DIFF) {
if (dictDelete(dstset->ptr,ele) == DICT_OK) {
cardinality--;
}
}
}
}
}
dictReleaseIterator(di);
dictReleaseIterator(di);
}
}
/* Output the content of the resulting set, if not in STORE mode */
if (!dstkey) {
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",cardinality));
di = dictGetIterator(dstset->ptr);
if (!di) oom("dictGetIterator");
while((de = dictNext(di)) != NULL) {
robj *ele;
ele = dictGetEntryKey(de);
addReplySds(c,sdscatprintf(sdsempty(),
"$%d\r\n",sdslen(ele->ptr)));
addReply(c,ele);
addReply(c,shared.crlf);
}
dictReleaseIterator(di);
}
/* Cleanup */
if (!dstkey) {
if (!dstkey) {
lenobj
->
ptr
=
sdscatprintf
(
sdsempty
(),
"*%d
\r\n
"
,
cardinality
);
decrRefCount(dstset);
decrRefCount(dstset);
} else {
} else {
addReply(c,shared.ok);
addReply(c,shared.ok);
...
@@ -3144,11 +3164,19 @@ static void sunionGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
...
@@ -3144,11 +3164,19 @@ static void sunionGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
}
}
static void sunionCommand(redisClient *c) {
static void sunionCommand(redisClient *c) {
sunionGenericCommand
(
c
,
c
->
argv
+
1
,
c
->
argc
-
1
,
NULL
);
sunion
Diff
GenericCommand(c,c->argv+1,c->argc-1,NULL
,REDIS_OP_UNION
);
}
}
static void sunionstoreCommand(redisClient *c) {
static void sunionstoreCommand(redisClient *c) {
sunionGenericCommand
(
c
,
c
->
argv
+
2
,
c
->
argc
-
2
,
c
->
argv
[
1
]);
sunionDiffGenericCommand(c,c->argv+2,c->argc-2,c->argv[1],REDIS_OP_UNION);
}
static void sdiffCommand(redisClient *c) {
sunionDiffGenericCommand(c,c->argv+1,c->argc-1,NULL,REDIS_OP_DIFF);
}
static void sdiffstoreCommand(redisClient *c) {
sunionDiffGenericCommand(c,c->argv+2,c->argc-2,c->argv[1],REDIS_OP_DIFF);
}
}
static void flushdbCommand(redisClient *c) {
static void flushdbCommand(redisClient *c) {
...
...
test-redis.tcl
View file @
f4f56e1d
...
@@ -498,6 +498,23 @@ proc main {server port} {
...
@@ -498,6 +498,23 @@ proc main {server port} {
lsort
[
$r
sunion nokey1 set1 set2 nokey2
]
lsort
[
$r
sunion nokey1 set1 set2 nokey2
]
}
[
lsort -uniq
"
[
$r
smembers set1
]
[
$r
smembers set2
]
"
]
}
[
lsort -uniq
"
[
$r
smembers set1
]
[
$r
smembers set2
]
"
]
test
{
SDIFF with two sets
}
{
for
{
set i 5
}
{
$i
< 1000
}
{
incr i
}
{
$r sadd set4 $i
}
lsort
[
$r
sdiff set1 set4
]
}
{
0 1 2 3 4
}
test
{
SDIFF with three sets
}
{
$r sadd set5 0
lsort
[
$r
sdiff set1 set4 set5
]
}
{
1 2 3 4
}
test
{
SDIFFSTORE with three sets
}
{
$r sdiffstore sres set1 set4 set5
lsort
[
$r
smembers sres
]
}
{
1 2 3 4
}
test
{
SAVE - make sure there are all the types as values
}
{
test
{
SAVE - make sure there are all the types as values
}
{
$r lpush mysavelist hello
$r lpush mysavelist hello
$r lpush mysavelist world
$r lpush mysavelist world
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment