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
45df42c9
Commit
45df42c9
authored
May 31, 2011
by
antirez
Browse files
Variadic ZADD
parent
6e326c81
Changes
2
Show whitespace changes
Inline
Side-by-side
src/redis.c
View file @
45df42c9
...
@@ -116,7 +116,7 @@ struct redisCommand readonlyCommandTable[] = {
...
@@ -116,7 +116,7 @@ struct redisCommand readonlyCommandTable[] = {
{
"sdiff"
,
sdiffCommand
,
-
2
,
REDIS_CMD_DENYOOM
,
NULL
,
1
,
-
1
,
1
},
{
"sdiff"
,
sdiffCommand
,
-
2
,
REDIS_CMD_DENYOOM
,
NULL
,
1
,
-
1
,
1
},
{
"sdiffstore"
,
sdiffstoreCommand
,
-
3
,
REDIS_CMD_DENYOOM
,
NULL
,
2
,
-
1
,
1
},
{
"sdiffstore"
,
sdiffstoreCommand
,
-
3
,
REDIS_CMD_DENYOOM
,
NULL
,
2
,
-
1
,
1
},
{
"smembers"
,
sinterCommand
,
2
,
0
,
NULL
,
1
,
1
,
1
},
{
"smembers"
,
sinterCommand
,
2
,
0
,
NULL
,
1
,
1
,
1
},
{
"zadd"
,
zaddCommand
,
4
,
REDIS_CMD_DENYOOM
,
NULL
,
1
,
1
,
1
},
{
"zadd"
,
zaddCommand
,
-
4
,
REDIS_CMD_DENYOOM
,
NULL
,
1
,
1
,
1
},
{
"zincrby"
,
zincrbyCommand
,
4
,
REDIS_CMD_DENYOOM
,
NULL
,
1
,
1
,
1
},
{
"zincrby"
,
zincrbyCommand
,
4
,
REDIS_CMD_DENYOOM
,
NULL
,
1
,
1
,
1
},
{
"zrem"
,
zremCommand
,
-
3
,
0
,
NULL
,
1
,
1
,
1
},
{
"zrem"
,
zremCommand
,
-
3
,
0
,
NULL
,
1
,
1
,
1
},
{
"zremrangebyscore"
,
zremrangebyscoreCommand
,
4
,
0
,
NULL
,
1
,
1
,
1
},
{
"zremrangebyscore"
,
zremrangebyscoreCommand
,
4
,
0
,
NULL
,
1
,
1
,
1
},
...
...
src/t_zset.c
View file @
45df42c9
...
@@ -816,11 +816,29 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -816,11 +816,29 @@ void zaddGenericCommand(redisClient *c, int incr) {
robj
*
ele
;
robj
*
ele
;
robj
*
zobj
;
robj
*
zobj
;
robj
*
curobj
;
robj
*
curobj
;
double
score
,
curscore
=
0
.
0
;
double
score
=
0
,
*
scores
,
curscore
=
0
.
0
;
int
j
,
elements
=
(
c
->
argc
-
2
)
/
2
;
int
added
=
0
;
if
(
getDoubleFromObjectOrReply
(
c
,
c
->
argv
[
2
],
&
score
,
NULL
)
!=
REDIS_OK
)
if
(
c
->
argc
%
2
)
{
addReply
(
c
,
shared
.
syntaxerr
);
return
;
}
/* Start parsing all the scores, we need to emit any syntax error
* before executing additions to the sorted set, as the command should
* either execute fully or nothing at all. */
scores
=
zmalloc
(
sizeof
(
double
)
*
elements
);
for
(
j
=
0
;
j
<
elements
;
j
++
)
{
if
(
getDoubleFromObjectOrReply
(
c
,
c
->
argv
[
2
+
j
*
2
],
&
scores
[
j
],
NULL
)
!=
REDIS_OK
)
{
zfree
(
scores
);
return
;
return
;
}
}
/* Lookup the key and create the sorted set if does not exist. */
zobj
=
lookupKeyWrite
(
c
->
db
,
key
);
zobj
=
lookupKeyWrite
(
c
->
db
,
key
);
if
(
zobj
==
NULL
)
{
if
(
zobj
==
NULL
)
{
if
(
server
.
zset_max_ziplist_entries
==
0
||
if
(
server
.
zset_max_ziplist_entries
==
0
||
...
@@ -834,22 +852,27 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -834,22 +852,27 @@ void zaddGenericCommand(redisClient *c, int incr) {
}
else
{
}
else
{
if
(
zobj
->
type
!=
REDIS_ZSET
)
{
if
(
zobj
->
type
!=
REDIS_ZSET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
addReply
(
c
,
shared
.
wrongtypeerr
);
zfree
(
scores
);
return
;
return
;
}
}
}
}
for
(
j
=
0
;
j
<
elements
;
j
++
)
{
score
=
scores
[
j
];
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
unsigned
char
*
eptr
;
unsigned
char
*
eptr
;
/* Prefer non-encoded element when dealing with ziplists. */
/* Prefer non-encoded element when dealing with ziplists. */
ele
=
c
->
argv
[
3
];
ele
=
c
->
argv
[
3
+
j
*
2
];
if
((
eptr
=
zzlFind
(
zobj
->
ptr
,
ele
,
&
curscore
))
!=
NULL
)
{
if
((
eptr
=
zzlFind
(
zobj
->
ptr
,
ele
,
&
curscore
))
!=
NULL
)
{
if
(
incr
)
{
if
(
incr
)
{
score
+=
curscore
;
score
+=
curscore
;
if
(
isnan
(
score
))
{
if
(
isnan
(
score
))
{
addReplyError
(
c
,
nanerr
);
addReplyError
(
c
,
nanerr
);
/* Don't need to check if the sorted set is empty, because
/* Don't need to check if the sorted set is empty
* we know it has at least one element. */
* because we know it has at least one element. */
zfree
(
scores
);
return
;
return
;
}
}
}
}
...
@@ -862,14 +885,9 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -862,14 +885,9 @@ void zaddGenericCommand(redisClient *c, int incr) {
signalModifiedKey
(
c
->
db
,
key
);
signalModifiedKey
(
c
->
db
,
key
);
server
.
dirty
++
;
server
.
dirty
++
;
}
}
if
(
incr
)
/* ZINCRBY */
addReplyDouble
(
c
,
score
);
else
/* ZADD */
addReply
(
c
,
shared
.
czero
);
}
else
{
}
else
{
/* Optimize: check if the element is too large or the list
becomes
/* Optimize: check if the element is too large or the list
*
too long *before* executing zzlInsert. */
* becomes
too long *before* executing zzlInsert. */
zobj
->
ptr
=
zzlInsert
(
zobj
->
ptr
,
ele
,
score
);
zobj
->
ptr
=
zzlInsert
(
zobj
->
ptr
,
ele
,
score
);
if
(
zzlLength
(
zobj
->
ptr
)
>
server
.
zset_max_ziplist_entries
)
if
(
zzlLength
(
zobj
->
ptr
)
>
server
.
zset_max_ziplist_entries
)
zsetConvert
(
zobj
,
REDIS_ENCODING_SKIPLIST
);
zsetConvert
(
zobj
,
REDIS_ENCODING_SKIPLIST
);
...
@@ -878,18 +896,14 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -878,18 +896,14 @@ void zaddGenericCommand(redisClient *c, int incr) {
signalModifiedKey
(
c
->
db
,
key
);
signalModifiedKey
(
c
->
db
,
key
);
server
.
dirty
++
;
server
.
dirty
++
;
if
(
!
incr
)
added
++
;
if
(
incr
)
/* ZINCRBY */
addReplyDouble
(
c
,
score
);
else
/* ZADD */
addReply
(
c
,
shared
.
cone
);
}
}
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_SKIPLIST
)
{
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_SKIPLIST
)
{
zset
*
zs
=
zobj
->
ptr
;
zset
*
zs
=
zobj
->
ptr
;
zskiplistNode
*
znode
;
zskiplistNode
*
znode
;
dictEntry
*
de
;
dictEntry
*
de
;
ele
=
c
->
argv
[
3
]
=
tryObjectEncoding
(
c
->
argv
[
3
]);
ele
=
c
->
argv
[
3
+
j
*
2
]
=
tryObjectEncoding
(
c
->
argv
[
3
+
j
*
2
]);
de
=
dictFind
(
zs
->
dict
,
ele
);
de
=
dictFind
(
zs
->
dict
,
ele
);
if
(
de
!=
NULL
)
{
if
(
de
!=
NULL
)
{
curobj
=
dictGetEntryKey
(
de
);
curobj
=
dictGetEntryKey
(
de
);
...
@@ -899,15 +913,16 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -899,15 +913,16 @@ void zaddGenericCommand(redisClient *c, int incr) {
score
+=
curscore
;
score
+=
curscore
;
if
(
isnan
(
score
))
{
if
(
isnan
(
score
))
{
addReplyError
(
c
,
nanerr
);
addReplyError
(
c
,
nanerr
);
/* Don't need to check if the sorted set is empty, because
/* Don't need to check if the sorted set is empty
* we know it has at least one element. */
* because we know it has at least one element. */
zfree
(
scores
);
return
;
return
;
}
}
}
}
/* Remove and re-insert when score changed. We can safely
delete
/* Remove and re-insert when score changed. We can safely
*
the key object from the skiplist, since the
dictionary still has
* delete
the key object from the skiplist, since the
*
a reference to it. */
* dictionary still has
a reference to it. */
if
(
score
!=
curscore
)
{
if
(
score
!=
curscore
)
{
redisAssert
(
zslDelete
(
zs
->
zsl
,
curscore
,
curobj
));
redisAssert
(
zslDelete
(
zs
->
zsl
,
curscore
,
curobj
));
znode
=
zslInsert
(
zs
->
zsl
,
score
,
curobj
);
znode
=
zslInsert
(
zs
->
zsl
,
score
,
curobj
);
...
@@ -917,11 +932,6 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -917,11 +932,6 @@ void zaddGenericCommand(redisClient *c, int incr) {
signalModifiedKey
(
c
->
db
,
key
);
signalModifiedKey
(
c
->
db
,
key
);
server
.
dirty
++
;
server
.
dirty
++
;
}
}
if
(
incr
)
/* ZINCRBY */
addReplyDouble
(
c
,
score
);
else
/* ZADD */
addReply
(
c
,
shared
.
czero
);
}
else
{
}
else
{
znode
=
zslInsert
(
zs
->
zsl
,
score
,
ele
);
znode
=
zslInsert
(
zs
->
zsl
,
score
,
ele
);
incrRefCount
(
ele
);
/* Inserted in skiplist. */
incrRefCount
(
ele
);
/* Inserted in skiplist. */
...
@@ -930,15 +940,17 @@ void zaddGenericCommand(redisClient *c, int incr) {
...
@@ -930,15 +940,17 @@ void zaddGenericCommand(redisClient *c, int incr) {
signalModifiedKey
(
c
->
db
,
key
);
signalModifiedKey
(
c
->
db
,
key
);
server
.
dirty
++
;
server
.
dirty
++
;
if
(
!
incr
)
added
++
;
if
(
incr
)
/* ZINCRBY */
addReplyDouble
(
c
,
score
);
else
/* ZADD */
addReply
(
c
,
shared
.
cone
);
}
}
}
else
{
}
else
{
redisPanic
(
"Unknown sorted set encoding"
);
redisPanic
(
"Unknown sorted set encoding"
);
}
}
}
zfree
(
scores
);
if
(
incr
)
/* ZINCRBY */
addReplyDouble
(
c
,
score
);
else
/* ZADD */
addReplyLongLong
(
c
,
added
);
}
}
void
zaddCommand
(
redisClient
*
c
)
{
void
zaddCommand
(
redisClient
*
c
)
{
...
...
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