Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
5d32abbb
Commit
5d32abbb
authored
May 29, 2015
by
antirez
Browse files
ZADD NX and XX options
parent
382a9434
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/t_zset.c
View file @
5d32abbb
...
...
@@ -1183,7 +1183,14 @@ void zaddGenericCommand(redisClient *c, int flags) {
robj
*
curobj
;
double
score
=
0
,
*
scores
=
NULL
,
curscore
=
0
.
0
;
int
j
,
elements
;
int
added
=
0
,
updated
=
0
,
scoreidx
=
0
;
int
scoreidx
=
0
;
/* The following vars are used in order to track what the command actually
* did during the execution, to reply to the client and to trigger the
* notification of keyspace change. */
int
added
=
0
;
/* Number of new elements added. */
int
updated
=
0
;
/* Number of elements with updated score. */
int
processed
=
0
;
/* Number of elements processed, may remain zero with
options like XX. */
/* Parse options. At the end 'scoreidx' is set to the argument position
* of the score of the first score-element pair. */
...
...
@@ -1236,6 +1243,7 @@ void zaddGenericCommand(redisClient *c, int flags) {
/* Lookup the key and create the sorted set if does not exist. */
zobj
=
lookupKeyWrite
(
c
->
db
,
key
);
if
(
zobj
==
NULL
)
{
if
(
xx
)
goto
reply_to_client
;
/* No key + XX option: nothing to do. */
if
(
server
.
zset_max_ziplist_entries
==
0
||
server
.
zset_max_ziplist_value
<
sdslen
(
c
->
argv
[
3
]
->
ptr
))
{
...
...
@@ -1260,6 +1268,7 @@ void zaddGenericCommand(redisClient *c, int flags) {
/* Prefer non-encoded element when dealing with ziplists. */
ele
=
c
->
argv
[
scoreidx
+
1
+
j
*
2
];
if
((
eptr
=
zzlFind
(
zobj
->
ptr
,
ele
,
&
curscore
))
!=
NULL
)
{
if
(
nx
)
continue
;
if
(
incr
)
{
score
+=
curscore
;
if
(
isnan
(
score
))
{
...
...
@@ -1275,7 +1284,8 @@ void zaddGenericCommand(redisClient *c, int flags) {
server
.
dirty
++
;
updated
++
;
}
}
else
{
processed
++
;
}
else
if
(
!
xx
)
{
/* Optimize: check if the element is too large or the list
* becomes too long *before* executing zzlInsert. */
zobj
->
ptr
=
zzlInsert
(
zobj
->
ptr
,
ele
,
score
);
...
...
@@ -1285,6 +1295,7 @@ void zaddGenericCommand(redisClient *c, int flags) {
zsetConvert
(
zobj
,
REDIS_ENCODING_SKIPLIST
);
server
.
dirty
++
;
added
++
;
processed
++
;
}
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_SKIPLIST
)
{
zset
*
zs
=
zobj
->
ptr
;
...
...
@@ -1295,6 +1306,7 @@ void zaddGenericCommand(redisClient *c, int flags) {
tryObjectEncoding
(
c
->
argv
[
scoreidx
+
1
+
j
*
2
]);
de
=
dictFind
(
zs
->
dict
,
ele
);
if
(
de
!=
NULL
)
{
if
(
nx
)
continue
;
curobj
=
dictGetKey
(
de
);
curscore
=
*
(
double
*
)
dictGetVal
(
de
);
...
...
@@ -1319,22 +1331,30 @@ void zaddGenericCommand(redisClient *c, int flags) {
server
.
dirty
++
;
updated
++
;
}
}
else
{
processed
++
;
}
else
if
(
!
xx
)
{
znode
=
zslInsert
(
zs
->
zsl
,
score
,
ele
);
incrRefCount
(
ele
);
/* Inserted in skiplist. */
redisAssertWithInfo
(
c
,
NULL
,
dictAdd
(
zs
->
dict
,
ele
,
&
znode
->
score
)
==
DICT_OK
);
incrRefCount
(
ele
);
/* Added to dictionary. */
server
.
dirty
++
;
added
++
;
processed
++
;
}
}
else
{
redisPanic
(
"Unknown sorted set encoding"
);
}
}
if
(
incr
)
/* ZINCRBY */
addReplyDouble
(
c
,
score
);
else
/* ZADD */
reply_to_client:
if
(
incr
)
{
/* ZINCRBY or INCR option. */
if
(
processed
)
addReplyDouble
(
c
,
score
);
else
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
/* ZADD. */
addReplyLongLong
(
c
,
added
);
}
cleanup:
zfree
(
scores
);
...
...
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