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
b978abbf
Commit
b978abbf
authored
Jun 13, 2010
by
Pieter Noordhuis
Browse files
small refactor of SMOVE and tests for SMOVE on sets with different encoding
parent
d0b58d53
Changes
2
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
b978abbf
...
@@ -5694,37 +5694,46 @@ static void sremCommand(redisClient *c) {
...
@@ -5694,37 +5694,46 @@ static void sremCommand(redisClient *c) {
}
}
static
void
smoveCommand
(
redisClient
*
c
)
{
static
void
smoveCommand
(
redisClient
*
c
)
{
robj
*
srcset
,
*
dstset
;
robj
*
srcset
,
*
dstset
,
*
ele
;
srcset
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
srcset
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
dstset
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
2
]);
dstset
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
2
]);
ele
=
c
->
argv
[
3
];
/* If the source key does not exist return 0, if it's of the wrong type
/* If the source key does not exist return 0 */
* raise an error */
if
(
srcset
==
NULL
)
{
if
(
srcset
==
NULL
||
srcset
->
type
!=
REDIS_SET
)
{
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
srcset
?
shared
.
wrongtypeerr
:
shared
.
czero
);
return
;
return
;
}
}
/* Error if the destination key is not a set as well */
if
(
dstset
&&
dstset
->
type
!=
REDIS_SET
)
{
/* If the source key has the wrong type, or the destination key
addReply
(
c
,
shared
.
wrongtypeerr
);
* is set and has the wrong type, return with an error. */
if
(
checkType
(
c
,
srcset
,
REDIS_SET
)
||
(
dstset
&&
checkType
(
c
,
dstset
,
REDIS_SET
)))
return
;
/* If srcset and dstset are equal, SMOVE is a no-op */
if
(
srcset
==
dstset
)
{
addReply
(
c
,
shared
.
cone
);
return
;
return
;
}
}
/* Remove the element from the source set */
if
(
!
setTypeRemove
(
srcset
,
c
->
argv
[
3
]))
{
/* If the element cannot be removed from the
src
set,
return 0. */
/* Key not found in the
src
set
! return zero */
if
(
!
setTypeRemove
(
srcset
,
ele
))
{
addReply
(
c
,
shared
.
czero
);
addReply
(
c
,
shared
.
czero
);
return
;
return
;
}
}
if
(
setTypeSize
(
srcset
)
==
0
&&
srcset
!=
dstset
)
dbDelete
(
c
->
db
,
c
->
argv
[
1
]);
/* Remove the src set from the database when empty */
if
(
setTypeSize
(
srcset
)
==
0
)
dbDelete
(
c
->
db
,
c
->
argv
[
1
]);
server
.
dirty
++
;
server
.
dirty
++
;
/* Add the element to the destination set */
/* Create the destination set when it doesn't exist */
if
(
!
dstset
)
{
if
(
!
dstset
)
{
dstset
=
setTypeCreate
(
c
->
argv
[
3
]
);
dstset
=
setTypeCreate
(
ele
);
dbAdd
(
c
->
db
,
c
->
argv
[
2
],
dstset
);
dbAdd
(
c
->
db
,
c
->
argv
[
2
],
dstset
);
}
}
setTypeAdd
(
dstset
,
c
->
argv
[
3
]);
/* An extra key has changed when ele was successfully added to dstset */
if
(
setTypeAdd
(
dstset
,
ele
))
server
.
dirty
++
;
addReply
(
c
,
shared
.
cone
);
addReply
(
c
,
shared
.
cone
);
}
}
...
...
tests/unit/type/set.tcl
View file @
b978abbf
...
@@ -180,38 +180,73 @@ start_server {tags {"set"}} {
...
@@ -180,38 +180,73 @@ start_server {tags {"set"}} {
}
}
}
}
test
{
SMOVE basics
}
{
proc setup_move
{}
{
r sadd myset1 a
r del myset3 myset4
r sadd myset1 b
create_set myset1
{
1 a b
}
r sadd myset1 c
create_set myset2
{
2 3 4
}
r sadd myset2 x
assert_encoding hashtable myset1
r sadd myset2 y
assert_encoding intset myset2
r sadd myset2 z
}
r smove myset1 myset2 a
list
[
lsort
[
r smembers myset2
]]
[
lsort
[
r smembers myset1
]]
test
"SMOVE basics - from regular set to intset"
{
}
{{
a x y z
}
{
b c
}}
# move a non-integer element to an intset should convert encoding
setup_move
test
{
SMOVE non existing key
}
{
assert_equal 1
[
r smove myset1 myset2 a
]
list
[
r smove myset1 myset2 foo
]
[
lsort
[
r smembers myset2
]]
[
lsort
[
r smembers myset1
]]
assert_equal
{
1 b
}
[
lsort
[
r smembers myset1
]]
}
{
0
{
a x y z
}
{
b c
}}
assert_equal
{
2 3 4 a
}
[
lsort
[
r smembers myset2
]]
assert_encoding hashtable myset2
test
{
SMOVE non existing src set
}
{
list
[
r smove noset myset2 foo
]
[
lsort
[
r smembers myset2
]]
# move an integer element should not convert the encoding
}
{
0
{
a x y z
}}
setup_move
assert_equal 1
[
r smove myset1 myset2 1
]
test
{
SMOVE non existing dst set
}
{
assert_equal
{
a b
}
[
lsort
[
r smembers myset1
]]
list
[
r smove myset2 myset3 y
]
[
lsort
[
r smembers myset2
]]
[
lsort
[
r smembers myset3
]]
assert_equal
{
1 2 3 4
}
[
lsort
[
r smembers myset2
]]
}
{
1
{
a x z
}
y
}
assert_encoding intset myset2
}
test
{
SMOVE wrong src key type
}
{
test
"SMOVE basics - from intset to regular set"
{
setup_move
assert_equal 1
[
r smove myset2 myset1 2
]
assert_equal
{
1 2 a b
}
[
lsort
[
r smembers myset1
]]
assert_equal
{
3 4
}
[
lsort
[
r smembers myset2
]]
}
test
"SMOVE non existing key"
{
setup_move
assert_equal 0
[
r smove myset1 myset2 foo
]
assert_equal
{
1 a b
}
[
lsort
[
r smembers myset1
]]
assert_equal
{
2 3 4
}
[
lsort
[
r smembers myset2
]]
}
test
"SMOVE non existing src set"
{
setup_move
assert_equal 0
[
r smove noset myset2 foo
]
assert_equal
{
2 3 4
}
[
lsort
[
r smembers myset2
]]
}
test
"SMOVE from regular set to non existing destination set"
{
setup_move
assert_equal 1
[
r smove myset1 myset3 a
]
assert_equal
{
1 b
}
[
lsort
[
r smembers myset1
]]
assert_equal
{
a
}
[
lsort
[
r smembers myset3
]]
assert_encoding hashtable myset3
}
test
"SMOVE from intset to non existing destination set"
{
setup_move
assert_equal 1
[
r smove myset2 myset3 2
]
assert_equal
{
3 4
}
[
lsort
[
r smembers myset2
]]
assert_equal
{
2
}
[
lsort
[
r smembers myset3
]]
assert_encoding intset myset3
}
test
"SMOVE wrong src key type"
{
r set x 10
r set x 10
catch
{
r smove x myset2 foo
}
err
assert_error
"ERR*wrong kind*"
{
r smove x myset2 foo
}
format $err
}
}
{
ERR*
}
test
{
SMOVE wrong dst key type
}
{
test
"
SMOVE wrong dst key type
"
{
r set x 10
r set x 10
catch
{
r smove myset2 x foo
}
err
assert_error
"ERR*wrong kind*"
{
r smove myset2 x foo
}
format $err
}
}
{
ERR*
}
}
}
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