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
dd88747b
Commit
dd88747b
authored
Mar 15, 2010
by
antirez
Browse files
pretty big refactoring
parent
92b27fe9
Changes
1
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
dd88747b
...
@@ -2478,6 +2478,13 @@ static void addReplyLong(redisClient *c, long l) {
...
@@ -2478,6 +2478,13 @@ static void addReplyLong(redisClient *c, long l) {
char buf[128];
char buf[128];
size_t len;
size_t len;
if (l == 0) {
addReply(c,shared.czero);
return;
} else if (l == 1) {
addReply(c,shared.cone);
return;
}
len = snprintf(buf,sizeof(buf),":%ld\r\n",l);
len = snprintf(buf,sizeof(buf),":%ld\r\n",l);
addReplySds(c,sdsnewlen(buf,len));
addReplySds(c,sdsnewlen(buf,len));
}
}
...
@@ -2486,6 +2493,13 @@ static void addReplyUlong(redisClient *c, unsigned long ul) {
...
@@ -2486,6 +2493,13 @@ static void addReplyUlong(redisClient *c, unsigned long ul) {
char buf[128];
char buf[128];
size_t len;
size_t len;
if (ul == 0) {
addReply(c,shared.czero);
return;
} else if (ul == 1) {
addReply(c,shared.cone);
return;
}
len = snprintf(buf,sizeof(buf),":%lu\r\n",ul);
len = snprintf(buf,sizeof(buf),":%lu\r\n",ul);
addReplySds(c,sdsnewlen(buf,len));
addReplySds(c,sdsnewlen(buf,len));
}
}
...
@@ -2511,6 +2525,12 @@ static void addReplyBulkLen(redisClient *c, robj *obj) {
...
@@ -2511,6 +2525,12 @@ static void addReplyBulkLen(redisClient *c, robj *obj) {
addReplySds(c,sdscatprintf(sdsempty(),"$%lu\r\n",(unsigned long)len));
addReplySds(c,sdscatprintf(sdsempty(),"$%lu\r\n",(unsigned long)len));
}
}
static void addReplyBulk(redisClient *c, robj *obj) {
addReplyBulkLen(c,obj);
addReply(c,obj);
addReply(c,shared.crlf);
}
static void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
static void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
int cport, cfd;
int cport, cfd;
char cip[128];
char cip[128];
...
@@ -3682,9 +3702,7 @@ static void pingCommand(redisClient *c) {
...
@@ -3682,9 +3702,7 @@ static void pingCommand(redisClient *c) {
}
}
static void echoCommand(redisClient *c) {
static void echoCommand(redisClient *c) {
addReplyBulkLen
(
c
,
c
->
argv
[
1
]);
addReplyBulk(c,c->argv[1]);
addReply
(
c
,
c
->
argv
[
1
]);
addReply
(
c
,
shared
.
crlf
);
}
}
/*=================================== Strings =============================== */
/*=================================== Strings =============================== */
...
@@ -3726,21 +3744,17 @@ static void setnxCommand(redisClient *c) {
...
@@ -3726,21 +3744,17 @@ static void setnxCommand(redisClient *c) {
}
}
static int getGenericCommand(redisClient *c) {
static int getGenericCommand(redisClient *c) {
robj
*
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
robj *o;
if
(
o
==
NULL
)
{
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL)
addReply
(
c
,
shared
.
nullbulk
);
return REDIS_OK;
return REDIS_OK;
if (o->type != REDIS_STRING) {
addReply(c,shared.wrongtypeerr);
return REDIS_ERR;
} else {
} else {
if
(
o
->
type
!=
REDIS_STRING
)
{
addReplyBulk(c,o);
addReply
(
c
,
shared
.
wrongtypeerr
);
return REDIS_OK;
return
REDIS_ERR
;
}
else
{
addReplyBulkLen
(
c
,
o
);
addReply
(
c
,
o
);
addReply
(
c
,
shared
.
crlf
);
return
REDIS_OK
;
}
}
}
}
}
...
@@ -3772,9 +3786,7 @@ static void mgetCommand(redisClient *c) {
...
@@ -3772,9 +3786,7 @@ static void mgetCommand(redisClient *c) {
if (o->type != REDIS_STRING) {
if (o->type != REDIS_STRING) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
} else {
} else {
addReplyBulkLen
(
c
,
o
);
addReplyBulk(c,o);
addReply
(
c
,
o
);
addReply
(
c
,
shared
.
crlf
);
}
}
}
}
}
}
...
@@ -3934,44 +3946,37 @@ static void substrCommand(redisClient *c) {
...
@@ -3934,44 +3946,37 @@ static void substrCommand(redisClient *c) {
robj *o;
robj *o;
long start = atoi(c->argv[2]->ptr);
long start = atoi(c->argv[2]->ptr);
long end = atoi(c->argv[3]->ptr);
long end = atoi(c->argv[3]->ptr);
size_t rangelen, strlen;
sds range;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
if
(
o
==
NULL
)
{
checkType(c,o,REDIS_STRING)) return;
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
if
(
o
->
type
!=
REDIS_STRING
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
size_t
rangelen
,
strlen
;
sds
range
;
o
=
getDecodedObject
(
o
);
strlen
=
sdslen
(
o
->
ptr
);
/* convert negative indexes */
o = getDecodedObject(o);
if
(
start
<
0
)
start
=
strlen
+
start
;
strlen = sdslen(o->ptr);
if
(
end
<
0
)
end
=
strlen
+
end
;
if
(
start
<
0
)
start
=
0
;
if
(
end
<
0
)
end
=
0
;
/* indexes sanity checks */
/* convert negative indexes */
if
(
start
>
end
||
(
size_t
)
start
>=
strlen
)
{
if (start < 0) start = strlen+start;
/* Out of range start or start > end result in null reply */
if (end < 0) end = strlen+end;
addReply
(
c
,
shared
.
nullbulk
);
if (start < 0) start = 0;
decrRefCount
(
o
);
if (end < 0) end = 0;
return
;
}
if
((
size_t
)
end
>=
strlen
)
end
=
strlen
-
1
;
rangelen
=
(
end
-
start
)
+
1
;
/* Return the result */
/* indexes sanity checks */
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
"$%zu
\r\n
"
,
rangelen
));
if (start > end || (size_t)start >= strlen) {
range
=
sdsnewlen
((
char
*
)
o
->
ptr
+
start
,
rangelen
);
/* Out of range start or start > end result in null reply */
addReplySds
(
c
,
range
);
addReply(c,shared.nullbulk);
addReply
(
c
,
shared
.
crlf
);
decrRefCount(o);
decrRefCount
(
o
);
return;
}
}
}
if ((size_t)end >= strlen) end = strlen-1;
rangelen = (end-start)+1;
/* Return the result */
addReplySds(c,sdscatprintf(sdsempty(),"$%zu\r\n",rangelen));
range = sdsnewlen((char*)o->ptr+start,rangelen);
addReplySds(c,range);
addReply(c,shared.crlf);
decrRefCount(o);
}
}
/* ========================= Type agnostic commands ========================= */
/* ========================= Type agnostic commands ========================= */
...
@@ -3985,17 +3990,7 @@ static void delCommand(redisClient *c) {
...
@@ -3985,17 +3990,7 @@ static void delCommand(redisClient *c) {
deleted++;
deleted++;
}
}
}
}
switch
(
deleted
)
{
addReplyLong(c,deleted);
case
0
:
addReply
(
c
,
shared
.
czero
);
break
;
case
1
:
addReply
(
c
,
shared
.
cone
);
break
;
default:
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%d
\r\n
"
,
deleted
));
break
;
}
}
}
static void existsCommand(redisClient *c) {
static void existsCommand(redisClient *c) {
...
@@ -4047,9 +4042,7 @@ static void keysCommand(redisClient *c) {
...
@@ -4047,9 +4042,7 @@ static void keysCommand(redisClient *c) {
if ((pattern[0] == '*' && pattern[1] == '\0') ||
if ((pattern[0] == '*' && pattern[1] == '\0') ||
stringmatchlen(pattern,plen,key,sdslen(key),0)) {
stringmatchlen(pattern,plen,key,sdslen(key),0)) {
if (expireIfNeeded(c->db,keyobj) == 0) {
if (expireIfNeeded(c->db,keyobj) == 0) {
addReplyBulkLen
(
c
,
keyobj
);
addReplyBulk(c,keyobj);
addReply
(
c
,
keyobj
);
addReply
(
c
,
shared
.
crlf
);
numkeys++;
numkeys++;
}
}
}
}
...
@@ -4139,12 +4132,14 @@ static void shutdownCommand(redisClient *c) {
...
@@ -4139,12 +4132,14 @@ static void shutdownCommand(redisClient *c) {
if (server.vm_enabled) unlink(server.vm_swap_file);
if (server.vm_enabled) unlink(server.vm_swap_file);
exit(0);
exit(0);
} else {
} else {
/* Ooops.. error saving! The best we can do is to continue operating.
/* Ooops.. error saving! The best we can do is to continue
* Note that if there was a background saving process, in the next
* operating. Note that if there was a background saving process,
* cron() Redis will be notified that the background saving aborted,
* in the next cron() Redis will be notified that the background
* handling special stuff like slaves pending for synchronization... */
* saving aborted, handling special stuff like slaves pending for
* synchronization... */
redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit");
redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit");
addReplySds
(
c
,
sdsnew
(
"-ERR can't quit, problems saving the DB
\r\n
"
));
addReplySds(c,
sdsnew("-ERR can't quit, problems saving the DB\r\n"));
}
}
}
}
}
}
...
@@ -4158,11 +4153,9 @@ static void renameGenericCommand(redisClient *c, int nx) {
...
@@ -4158,11 +4153,9 @@ static void renameGenericCommand(redisClient *c, int nx) {
return;
return;
}
}
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL)
if
(
o
==
NULL
)
{
addReply
(
c
,
shared
.
nokeyerr
);
return;
return;
}
incrRefCount(o);
incrRefCount(o);
deleteIfVolatile(c->db,c->argv[2]);
deleteIfVolatile(c->db,c->argv[2]);
if (dictAdd(c->db->dict,c->argv[2],o) == DICT_ERR) {
if (dictAdd(c->db->dict,c->argv[2],o) == DICT_ERR) {
...
@@ -4285,107 +4278,78 @@ static void rpushCommand(redisClient *c) {
...
@@ -4285,107 +4278,78 @@ static void rpushCommand(redisClient *c) {
static void llenCommand(redisClient *c) {
static void llenCommand(redisClient *c) {
robj *o;
robj *o;
list *l;
list *l;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,o,REDIS_LIST)) return;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
l = o->ptr;
if
(
o
==
NULL
)
{
addReplyUlong(c,listLength(l));
addReply
(
c
,
shared
.
czero
);
return
;
}
else
{
if
(
o
->
type
!=
REDIS_LIST
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
l
=
o
->
ptr
;
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%d
\r\n
"
,
listLength
(
l
)));
}
}
}
}
static void lindexCommand(redisClient *c) {
static void lindexCommand(redisClient *c) {
robj *o;
robj *o;
int index = atoi(c->argv[2]->ptr);
int index = atoi(c->argv[2]->ptr);
list *list;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
listNode *ln;
if
(
o
==
NULL
)
{
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_LIST)) return;
list = o->ptr;
ln = listIndex(list, index);
if (ln == NULL) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
} else {
} else {
if
(
o
->
type
!=
REDIS_LIST
)
{
robj *ele = listNodeValue(ln);
addReply
(
c
,
shared
.
wrongtypeerr
);
addReplyBulk(c,ele);
}
else
{
list
*
list
=
o
->
ptr
;
listNode
*
ln
;
ln
=
listIndex
(
list
,
index
);
if
(
ln
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
robj
*
ele
=
listNodeValue
(
ln
);
addReplyBulkLen
(
c
,
ele
);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
}
}
}
}
}
}
static void lsetCommand(redisClient *c) {
static void lsetCommand(redisClient *c) {
robj *o;
robj *o;
int index = atoi(c->argv[2]->ptr);
int index = atoi(c->argv[2]->ptr);
list *list;
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
listNode *ln;
if
(
o
==
NULL
)
{
addReply
(
c
,
shared
.
nokeyerr
);
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL ||
checkType(c,o,REDIS_LIST)) return;
list = o->ptr;
ln = listIndex(list, index);
if (ln == NULL) {
addReply(c,shared.outofrangeerr);
} else {
} else {
if
(
o
->
type
!=
REDIS_LIST
)
{
robj *ele = listNodeValue(ln);
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
list
*
list
=
o
->
ptr
;
listNode
*
ln
;
ln
=
listIndex
(
list
,
index
);
if
(
ln
==
NULL
)
{
addReply
(
c
,
shared
.
outofrangeerr
);
}
else
{
robj
*
ele
=
listNodeValue
(
ln
);
decrRefCount
(
ele
);
decrRefCount(ele);
listNodeValue
(
ln
)
=
c
->
argv
[
3
];
listNodeValue(ln) = c->argv[3];
incrRefCount
(
c
->
argv
[
3
]);
incrRefCount(c->argv[3]);
addReply
(
c
,
shared
.
ok
);
addReply(c,shared.ok);
server
.
dirty
++
;
server.dirty++;
}
}
}
}
}
}
static void popGenericCommand(redisClient *c, int where) {
static void popGenericCommand(redisClient *c, int where) {
robj *o;
robj *o;
list *list;
listNode *ln;
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
if
(
o
==
NULL
)
{
checkType(c,o,REDIS_LIST)) return;
addReply
(
c
,
shared
.
nullbulk
);
list = o->ptr;
}
else
{
if
(
o
->
type
!=
REDIS_LIST
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
list
*
list
=
o
->
ptr
;
listNode
*
ln
;
if
(
where
==
REDIS_HEAD
)
if (where == REDIS_HEAD)
ln
=
listFirst
(
list
);
ln = listFirst(list);
else
else
ln
=
listLast
(
list
);
ln = listLast(list);
if
(
ln
==
NULL
)
{
if (ln == NULL) {
addReply
(
c
,
shared
.
nullbulk
);
addReply(c,shared.nullbulk);
}
else
{
} else {
robj
*
ele
=
listNodeValue
(
ln
);
robj *ele = listNodeValue(ln);
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
listDelNode(list,ln);
addReply
(
c
,
shared
.
crlf
);
server.dirty++;
listDelNode
(
list
,
ln
);
server
.
dirty
++
;
}
}
}
}
}
}
...
@@ -4401,46 +4365,39 @@ static void lrangeCommand(redisClient *c) {
...
@@ -4401,46 +4365,39 @@ static void lrangeCommand(redisClient *c) {
robj *o;
robj *o;
int start = atoi(c->argv[2]->ptr);
int start = atoi(c->argv[2]->ptr);
int end = atoi(c->argv[3]->ptr);
int end = atoi(c->argv[3]->ptr);
int llen;
int rangelen, j;
list *list;
listNode *ln;
robj *ele;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullmultibulk)) == NULL ||
checkType(c,o,REDIS_LIST)) return;
list = o->ptr;
llen = listLength(list);
/* convert negative indexes */
if (start < 0) start = llen+start;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
if (end < 0) end = 0;
/* indexes sanity checks */
if (start > end || start >= llen) {
/* Out of range start or start > end result in empty list */
addReply(c,shared.emptymultibulk);
return;
}
if (end >= llen) end = llen-1;
rangelen = (end-start)+1;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
/* Return the result in form of a multi-bulk reply */
if
(
o
==
NULL
)
{
ln = listIndex(list, start);
addReply
(
c
,
shared
.
nullmultibulk
);
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",rangelen));
}
else
{
for (j = 0; j < rangelen; j++) {
if
(
o
->
type
!=
REDIS_LIST
)
{
ele = listNodeValue(ln);
addReply
(
c
,
shared
.
wrongtypeerr
);
addReplyBulk(c,ele);
}
else
{
ln = ln->next;
list
*
list
=
o
->
ptr
;
listNode
*
ln
;
int
llen
=
listLength
(
list
);
int
rangelen
,
j
;
robj
*
ele
;
/* convert negative indexes */
if
(
start
<
0
)
start
=
llen
+
start
;
if
(
end
<
0
)
end
=
llen
+
end
;
if
(
start
<
0
)
start
=
0
;
if
(
end
<
0
)
end
=
0
;
/* indexes sanity checks */
if
(
start
>
end
||
start
>=
llen
)
{
/* Out of range start or start > end result in empty list */
addReply
(
c
,
shared
.
emptymultibulk
);
return
;
}
if
(
end
>=
llen
)
end
=
llen
-
1
;
rangelen
=
(
end
-
start
)
+
1
;
/* Return the result in form of a multi-bulk reply */
ln
=
listIndex
(
list
,
start
);
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
"*%d
\r\n
"
,
rangelen
));
for
(
j
=
0
;
j
<
rangelen
;
j
++
)
{
ele
=
listNodeValue
(
ln
);
addReplyBulkLen
(
c
,
ele
);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
ln
=
ln
->
next
;
}
}
}
}
}
}
...
@@ -4448,87 +4405,76 @@ static void ltrimCommand(redisClient *c) {
...
@@ -4448,87 +4405,76 @@ static void ltrimCommand(redisClient *c) {
robj *o;
robj *o;
int start = atoi(c->argv[2]->ptr);
int start = atoi(c->argv[2]->ptr);
int end = atoi(c->argv[3]->ptr);
int end = atoi(c->argv[3]->ptr);
int llen;
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
int j, ltrim, rtrim;
if
(
o
==
NULL
)
{
list *list;
addReply
(
c
,
shared
.
ok
);
listNode *ln;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.ok)) == NULL ||
checkType(c,o,REDIS_LIST)) return;
list = o->ptr;
llen = listLength(list);
/* convert negative indexes */
if (start < 0) start = llen+start;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
if (end < 0) end = 0;
/* indexes sanity checks */
if (start > end || start >= llen) {
/* Out of range start or start > end result in empty list */
ltrim = llen;
rtrim = 0;
} else {
} else {
if
(
o
->
type
!=
REDIS_LIST
)
{
if (end >= llen) end = llen-1;
addReply
(
c
,
shared
.
wrongtypeerr
);
ltrim = start;
}
else
{
rtrim = llen-end-1;
list
*
list
=
o
->
ptr
;
}
listNode
*
ln
;
int
llen
=
listLength
(
list
);
int
j
,
ltrim
,
rtrim
;
/* convert negative indexes */
if
(
start
<
0
)
start
=
llen
+
start
;
if
(
end
<
0
)
end
=
llen
+
end
;
if
(
start
<
0
)
start
=
0
;
if
(
end
<
0
)
end
=
0
;
/* indexes sanity checks */
if
(
start
>
end
||
start
>=
llen
)
{
/* Out of range start or start > end result in empty list */
ltrim
=
llen
;
rtrim
=
0
;
}
else
{
if
(
end
>=
llen
)
end
=
llen
-
1
;
ltrim
=
start
;
rtrim
=
llen
-
end
-
1
;
}
/* Remove list elements to perform the trim */
/* Remove list elements to perform the trim */
for
(
j
=
0
;
j
<
ltrim
;
j
++
)
{
for (j = 0; j < ltrim; j++) {
ln
=
listFirst
(
list
);
ln = listFirst(list);
listDelNode
(
list
,
ln
);
listDelNode(list,ln);
}
}
for
(
j
=
0
;
j
<
rtrim
;
j
++
)
{
for (j = 0; j < rtrim; j++) {
ln
=
listLast
(
list
);
ln = listLast(list);
listDelNode
(
list
,
ln
);
listDelNode(list,ln);
}
server
.
dirty
++
;
addReply
(
c
,
shared
.
ok
);
}
}
}
server.dirty++;
addReply(c,shared.ok);
}
}
static void lremCommand(redisClient *c) {
static void lremCommand(redisClient *c) {
robj *o;
robj *o;
list *list;
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
listNode *ln, *next;
if
(
o
==
NULL
)
{
int toremove = atoi(c->argv[2]->ptr);
addReply
(
c
,
shared
.
czero
);
int removed = 0;
}
else
{
int fromtail = 0;
if
(
o
->
type
!=
REDIS_LIST
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
list
*
list
=
o
->
ptr
;
listNode
*
ln
,
*
next
;
int
toremove
=
atoi
(
c
->
argv
[
2
]
->
ptr
);
int
removed
=
0
;
int
fromtail
=
0
;
if
(
toremove
<
0
)
{
toremove
=
-
toremove
;
fromtail
=
1
;
}
ln
=
fromtail
?
list
->
tail
:
list
->
head
;
while
(
ln
)
{
robj
*
ele
=
listNodeValue
(
ln
);
next
=
fromtail
?
ln
->
prev
:
ln
->
next
;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
compareStringObjects
(
ele
,
c
->
argv
[
3
])
==
0
)
{
checkType(c,o,REDIS_LIST)) return;
listDelNode
(
list
,
ln
);
list = o->ptr;
server
.
dirty
++
;
removed
++
;
if (toremove < 0) {
if
(
toremove
&&
removed
==
toremove
)
break
;
toremove = -toremove;
}
fromtail = 1;
ln
=
next
;
}
}
ln = fromtail ? list->tail : list->head;
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%d
\r\n
"
,
removed
));
while (ln) {
robj *ele = listNodeValue(ln);
next = fromtail ? ln->prev : ln->next;
if (compareStringObjects(ele,c->argv[3]) == 0) {
listDelNode(list,ln);
server.dirty++;
removed++;
if (toremove && removed == toremove) break;
}
}
ln = next;
}
}
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",removed));
}
}
/* This is the semantic of this command:
/* This is the semantic of this command:
...
@@ -4548,57 +4494,49 @@ static void lremCommand(redisClient *c) {
...
@@ -4548,57 +4494,49 @@ static void lremCommand(redisClient *c) {
*/
*/
static void rpoplpushcommand(redisClient *c) {
static void rpoplpushcommand(redisClient *c) {
robj *sobj;
robj *sobj;
list *srclist;
listNode *ln;
if ((sobj = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,sobj,REDIS_LIST)) return;
srclist = sobj->ptr;
ln = listLast(srclist);
sobj
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if (ln == NULL) {
if
(
sobj
==
NULL
)
{
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
} else {
} else {
if
(
sobj
->
type
!=
REDIS_LIST
)
{
robj *dobj = lookupKeyWrite(c->db,c->argv[2]);
addReply
(
c
,
shared
.
wrongtypeerr
);
robj *ele = listNodeValue(ln);
}
else
{
list *dstlist;
list
*
srclist
=
sobj
->
ptr
;
listNode
*
ln
=
listLast
(
srclist
);
if
(
ln
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
robj
*
dobj
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
2
]);
robj
*
ele
=
listNodeValue
(
ln
);
list
*
dstlist
;
if
(
dobj
&&
dobj
->
type
!=
REDIS_LIST
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
/* Add the element to the target list (unless it's directly
if (dobj && dobj->type != REDIS_LIST) {
* passed to some BLPOP-ing client */
addReply(c,shared.wrongtypeerr);
if
(
!
handleClientsWaitingListPush
(
c
,
c
->
argv
[
2
],
ele
))
{
return;
if
(
dobj
==
NULL
)
{
}
/* Create the list if the key does not exist */
dobj
=
createListObject
();
dictAdd
(
c
->
db
->
dict
,
c
->
argv
[
2
],
dobj
);
incrRefCount
(
c
->
argv
[
2
]);
}
dstlist
=
dobj
->
ptr
;
listAddNodeHead
(
dstlist
,
ele
);
incrRefCount
(
ele
);
}
/* Send the element to the client as reply as well */
addReplyBulkLen
(
c
,
ele
);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
/* Finally remove the element from the source list */
/* Add the element to the target list (unless it's directly
listDelNode
(
srclist
,
ln
);
* passed to some BLPOP-ing client */
server
.
dirty
++
;
if (!handleClientsWaitingListPush(c,c->argv[2],ele)) {
if (dobj == NULL) {
/* Create the list if the key does not exist */
dobj = createListObject();
dictAdd(c->db->dict,c->argv[2],dobj);
incrRefCount(c->argv[2]);
}
}
dstlist = dobj->ptr;
listAddNodeHead(dstlist,ele);
incrRefCount(ele);
}
}
/* Send the element to the client as reply as well */
addReplyBulk(c,ele);
/* Finally remove the element from the source list */
listDelNode(srclist,ln);
server.dirty++;
}
}
}
}
/* ==================================== Sets ================================ */
/* ==================================== Sets ================================ */
static void saddCommand(redisClient *c) {
static void saddCommand(redisClient *c) {
...
@@ -4627,21 +4565,15 @@ static void saddCommand(redisClient *c) {
...
@@ -4627,21 +4565,15 @@ static void saddCommand(redisClient *c) {
static void sremCommand(redisClient *c) {
static void sremCommand(redisClient *c) {
robj *set;
robj *set;
set
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
set
==
NULL
)
{
checkType(c,set,REDIS_SET)) return;
addReply
(
c
,
shared
.
czero
);
if (dictDelete(set->ptr,c->argv[2]) == DICT_OK) {
server.dirty++;
if (htNeedsResize(set->ptr)) dictResize(set->ptr);
addReply(c,shared.cone);
} else {
} else {
if
(
set
->
type
!=
REDIS_SET
)
{
addReply(c,shared.czero);
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
if
(
dictDelete
(
set
->
ptr
,
c
->
argv
[
2
])
==
DICT_OK
)
{
server
.
dirty
++
;
if
(
htNeedsResize
(
set
->
ptr
))
dictResize
(
set
->
ptr
);
addReply
(
c
,
shared
.
cone
);
}
else
{
addReply
(
c
,
shared
.
czero
);
}
}
}
}
}
...
@@ -4683,65 +4615,43 @@ static void smoveCommand(redisClient *c) {
...
@@ -4683,65 +4615,43 @@ static void smoveCommand(redisClient *c) {
static void sismemberCommand(redisClient *c) {
static void sismemberCommand(redisClient *c) {
robj *set;
robj *set;
set
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
set
==
NULL
)
{
checkType(c,set,REDIS_SET)) return;
if (dictFind(set->ptr,c->argv[2]))
addReply(c,shared.cone);
else
addReply(c,shared.czero);
addReply(c,shared.czero);
}
else
{
if
(
set
->
type
!=
REDIS_SET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
if
(
dictFind
(
set
->
ptr
,
c
->
argv
[
2
]))
addReply
(
c
,
shared
.
cone
);
else
addReply
(
c
,
shared
.
czero
);
}
}
}
static void scardCommand(redisClient *c) {
static void scardCommand(redisClient *c) {
robj *o;
robj *o;
dict *s;
dict *s;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,o,REDIS_SET)) return;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
s = o->ptr;
if
(
o
==
NULL
)
{
addReplyUlong(c,dictSize(s));
addReply
(
c
,
shared
.
czero
);
return
;
}
else
{
if
(
o
->
type
!=
REDIS_SET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
s
=
o
->
ptr
;
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%lu
\r\n
"
,
dictSize
(
s
)));
}
}
}
}
static void spopCommand(redisClient *c) {
static void spopCommand(redisClient *c) {
robj *set;
robj *set;
dictEntry *de;
dictEntry *de;
set
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
if
(
set
==
NULL
)
{
checkType(c,set,REDIS_SET)) return;
de = dictGetRandomKey(set->ptr);
if (de == NULL) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
} else {
} else {
if
(
set
->
type
!=
REDIS_SET
)
{
robj *ele = dictGetEntryKey(de);
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
de
=
dictGetRandomKey
(
set
->
ptr
);
if
(
de
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
robj
*
ele
=
dictGetEntryKey
(
de
);
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
dictDelete(set->ptr,ele);
addReply
(
c
,
shared
.
crlf
);
if (htNeedsResize(set->ptr)) dictResize(set->ptr);
dictDelete
(
set
->
ptr
,
ele
);
server.dirty++;
if
(
htNeedsResize
(
set
->
ptr
))
dictResize
(
set
->
ptr
);
server
.
dirty
++
;
}
}
}
}
}
...
@@ -4749,24 +4659,16 @@ static void srandmemberCommand(redisClient *c) {
...
@@ -4749,24 +4659,16 @@ static void srandmemberCommand(redisClient *c) {
robj *set;
robj *set;
dictEntry *de;
dictEntry *de;
set
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
if
(
set
==
NULL
)
{
checkType(c,set,REDIS_SET)) return;
de = dictGetRandomKey(set->ptr);
if (de == NULL) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
} else {
} else {
if
(
set
->
type
!=
REDIS_SET
)
{
robj *ele = dictGetEntryKey(de);
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
de
=
dictGetRandomKey
(
set
->
ptr
);
if
(
de
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
robj
*
ele
=
dictGetEntryKey
(
de
);
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
}
}
}
}
}
...
@@ -4840,9 +4742,7 @@ static void sinterGenericCommand(redisClient *c, robj **setskeys, unsigned long
...
@@ -4840,9 +4742,7 @@ static void sinterGenericCommand(redisClient *c, robj **setskeys, unsigned long
continue; /* at least one set does not contain the member */
continue; /* at least one set does not contain the member */
ele = dictGetEntryKey(de);
ele = dictGetEntryKey(de);
if (!dstkey) {
if (!dstkey) {
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
cardinality++;
cardinality++;
} else {
} else {
dictAdd(dstset->ptr,ele,NULL);
dictAdd(dstset->ptr,ele,NULL);
...
@@ -4947,9 +4847,7 @@ static void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnu
...
@@ -4947,9 +4847,7 @@ static void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnu
robj *ele;
robj *ele;
ele = dictGetEntryKey(de);
ele = dictGetEntryKey(de);
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
}
}
dictReleaseIterator(di);
dictReleaseIterator(di);
} else {
} else {
...
@@ -5284,11 +5182,11 @@ zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank) {
...
@@ -5284,11 +5182,11 @@ zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank) {
x = zsl->header;
x = zsl->header;
for (i = zsl->level-1; i >= 0; i--) {
for (i = zsl->level-1; i >= 0; i--) {
while
(
x
->
forward
[
i
]
&&
(
traversed
+
(
i
>
0
?
x
->
span
[
i
-
1
]
:
1
))
<=
rank
)
{
while (x->forward[i] && (traversed + (i>0 ? x->span[i-1] : 1)) <= rank)
{
traversed += i > 0 ? x->span[i-1] : 1;
traversed += i > 0 ? x->span[i-1] : 1;
x = x->forward[i];
x = x->forward[i];
}
}
if (traversed == rank) {
if (traversed == rank) {
return x;
return x;
}
}
...
@@ -5396,101 +5294,80 @@ static void zincrbyCommand(redisClient *c) {
...
@@ -5396,101 +5294,80 @@ static void zincrbyCommand(redisClient *c) {
static void zremCommand(redisClient *c) {
static void zremCommand(redisClient *c) {
robj *zsetobj;
robj *zsetobj;
zset *zs;
zset *zs;
dictEntry *de;
double *oldscore;
int deleted;
zsetobj
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
zsetobj
==
NULL
)
{
checkType(c,zsetobj,REDIS_ZSET)) return;
addReply
(
c
,
shared
.
czero
);
}
else
{
dictEntry
*
de
;
double
*
oldscore
;
int
deleted
;
if
(
zsetobj
->
type
!=
REDIS_ZSET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
zs
=
zsetobj
->
ptr
;
de
=
dictFind
(
zs
->
dict
,
c
->
argv
[
2
]);
if
(
de
==
NULL
)
{
addReply
(
c
,
shared
.
czero
);
return
;
}
/* Delete from the skiplist */
oldscore
=
dictGetEntryVal
(
de
);
deleted
=
zslDelete
(
zs
->
zsl
,
*
oldscore
,
c
->
argv
[
2
]);
redisAssert
(
deleted
!=
0
);
/* Delete from the hash table */
zs = zsetobj->ptr;
dict
Delete
(
zs
->
dict
,
c
->
argv
[
2
]);
de =
dict
Find
(zs->dict,c->argv[2]);
if
(
htNeedsResize
(
zs
->
dict
))
dictResize
(
zs
->
dict
);
if (
de == NULL) {
server
.
dirty
++
;
addReply(c,shared.czero)
;
addReply
(
c
,
shared
.
cone
)
;
return
;
}
}
/* Delete from the skiplist */
oldscore = dictGetEntryVal(de);
deleted = zslDelete(zs->zsl,*oldscore,c->argv[2]);
redisAssert(deleted != 0);
/* Delete from the hash table */
dictDelete(zs->dict,c->argv[2]);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
server.dirty++;
addReply(c,shared.cone);
}
}
static void zremrangebyscoreCommand(redisClient *c) {
static void zremrangebyscoreCommand(redisClient *c) {
double min = strtod(c->argv[2]->ptr,NULL);
double min = strtod(c->argv[2]->ptr,NULL);
double max = strtod(c->argv[3]->ptr,NULL);
double max = strtod(c->argv[3]->ptr,NULL);
long deleted;
robj *zsetobj;
robj *zsetobj;
zset *zs;
zset *zs;
zsetobj
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
zsetobj
==
NULL
)
{
checkType(c,zsetobj,REDIS_ZSET)) return;
addReply
(
c
,
shared
.
czero
);
}
else
{
long
deleted
;
if
(
zsetobj
->
type
!=
REDIS_ZSET
)
{
zs = zsetobj->ptr;
addReply
(
c
,
shared
.
wrongtypeerr
);
deleted = zslDeleteRangeByScore(zs->zsl,min,max,zs->dict);
return
;
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
}
server.dirty += deleted;
zs
=
zsetobj
->
ptr
;
addReplyLong(c,deleted);
deleted
=
zslDeleteRangeByScore
(
zs
->
zsl
,
min
,
max
,
zs
->
dict
);
if
(
htNeedsResize
(
zs
->
dict
))
dictResize
(
zs
->
dict
);
server
.
dirty
+=
deleted
;
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%lu
\r\n
"
,
deleted
));
}
}
}
static void zremrangebyrankCommand(redisClient *c) {
static void zremrangebyrankCommand(redisClient *c) {
int start = atoi(c->argv[2]->ptr);
int start = atoi(c->argv[2]->ptr);
int end = atoi(c->argv[3]->ptr);
int end = atoi(c->argv[3]->ptr);
int llen;
long deleted;
robj *zsetobj;
robj *zsetobj;
zset *zs;
zset *zs;
zsetobj
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
zsetobj
==
NULL
)
{
checkType(c,zsetobj,REDIS_ZSET)) return;
addReply
(
c
,
shared
.
czero
);
zs = zsetobj->ptr;
}
else
{
llen = zs->zsl->length;
if
(
zsetobj
->
type
!=
REDIS_ZSET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
return
;
}
zs
=
zsetobj
->
ptr
;
int
llen
=
zs
->
zsl
->
length
;
long
deleted
;
/* convert negative indexes */
if
(
start
<
0
)
start
=
llen
+
start
;
if
(
end
<
0
)
end
=
llen
+
end
;
if
(
start
<
0
)
start
=
0
;
if
(
end
<
0
)
end
=
0
;
/* indexes sanity checks */
/* convert negative indexes */
if
(
start
>
end
||
start
>=
llen
)
{
if (start < 0) start = llen+start;
addReply
(
c
,
shared
.
czero
);
if (end < 0) end = llen+end;
return
;
if (start < 0) start = 0;
}
if (end < 0) end = 0;
if
(
end
>=
llen
)
end
=
llen
-
1
;
/* increment start and end because zsl*Rank functions
/* indexes sanity checks */
* use 1-based rank */
if (start > end || start >= llen) {
deleted
=
zslDeleteRangeByRank
(
zs
->
zsl
,
start
+
1
,
end
+
1
,
zs
->
dict
);
addReply(c,shared.czero);
if
(
htNeedsResize
(
zs
->
dict
))
dictResize
(
zs
->
dict
);
return;
server
.
dirty
+=
deleted
;
addReplyLong
(
c
,
deleted
);
}
}
if (end >= llen) end = llen-1;
/* increment start and end because zsl*Rank functions
* use 1-based rank */
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
server.dirty += deleted;
addReplyLong(c, deleted);
}
}
typedef struct {
typedef struct {
...
@@ -5663,6 +5540,12 @@ static void zrangeGenericCommand(redisClient *c, int reverse) {
...
@@ -5663,6 +5540,12 @@ static void zrangeGenericCommand(redisClient *c, int reverse) {
int start = atoi(c->argv[2]->ptr);
int start = atoi(c->argv[2]->ptr);
int end = atoi(c->argv[3]->ptr);
int end = atoi(c->argv[3]->ptr);
int withscores = 0;
int withscores = 0;
int llen;
int rangelen, j;
zset *zsetobj;
zskiplist *zsl;
zskiplistNode *ln;
robj *ele;
if (c->argc == 5 && !strcasecmp(c->argv[4]->ptr,"withscores")) {
if (c->argc == 5 && !strcasecmp(c->argv[4]->ptr,"withscores")) {
withscores = 1;
withscores = 1;
...
@@ -5671,57 +5554,45 @@ static void zrangeGenericCommand(redisClient *c, int reverse) {
...
@@ -5671,57 +5554,45 @@ static void zrangeGenericCommand(redisClient *c, int reverse) {
return;
return;
}
}
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullmultibulk)) == NULL ||
if
(
o
==
NULL
)
{
checkType(c,o,REDIS_ZSET)) return;
addReply
(
c
,
shared
.
nullmultibulk
);
zsetobj = o->ptr;
}
else
{
zsl = zsetobj->zsl;
if
(
o
->
type
!=
REDIS_ZSET
)
{
llen = zsl->length;
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
zset
*
zsetobj
=
o
->
ptr
;
zskiplist
*
zsl
=
zsetobj
->
zsl
;
zskiplistNode
*
ln
;
int
llen
=
zsl
->
length
;
/* convert negative indexes */
int
rangelen
,
j
;
if (start < 0) start = llen+start;
robj
*
ele
;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
if (end < 0) end = 0;
/* convert negative indexes */
/* indexes sanity checks */
if
(
start
<
0
)
start
=
llen
+
start
;
if (start > end || start >= llen) {
if
(
end
<
0
)
end
=
llen
+
end
;
/* Out of range start or start > end result in empty list */
if
(
start
<
0
)
start
=
0
;
addReply(c,shared.emptymultibulk);
if
(
end
<
0
)
end
=
0
;
return;
}
/* indexes sanity checks */
if (end >= llen) end = llen-1;
if
(
start
>
end
||
start
>=
llen
)
{
rangelen = (end-start)+1;
/* Out of range start or start > end result in empty list */
addReply
(
c
,
shared
.
emptymultibulk
);
return
;
}
if
(
end
>=
llen
)
end
=
llen
-
1
;
rangelen
=
(
end
-
start
)
+
1
;
/* check if starting point is trivial, before searching
/* check if starting point is trivial, before searching
* the element in log(N) time */
* the element in log(N) time */
if
(
reverse
)
{
if (reverse) {
ln
=
start
==
0
?
zsl
->
tail
:
zslGetElementByRank
(
zsl
,
llen
-
start
);
ln = start == 0 ? zsl->tail : zslGetElementByRank(zsl, llen-start);
}
else
{
} else {
ln
=
start
==
0
?
zsl
->
header
->
forward
[
0
]
:
zslGetElementByRank
(
zsl
,
start
+
1
);
ln = start == 0 ?
}
zsl->header->forward[0] : zslGetElementByRank(zsl, start+1);
}
/* Return the result in form of a multi-bulk reply */
/* Return the result in form of a multi-bulk reply */
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
"*%d
\r\n
"
,
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",
withscores
?
(
rangelen
*
2
)
:
rangelen
));
withscores ? (rangelen*2) : rangelen));
for
(
j
=
0
;
j
<
rangelen
;
j
++
)
{
for (j = 0; j < rangelen; j++) {
ele
=
ln
->
obj
;
ele = ln->obj;
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
if (withscores)
addReply
(
c
,
shared
.
crlf
);
addReplyDouble(c,ln->score);
if
(
withscores
)
ln = reverse ? ln->backward : ln->forward[0];
addReplyDouble
(
c
,
ln
->
score
);
ln
=
reverse
?
ln
->
backward
:
ln
->
forward
[
0
];
}
}
}
}
}
}
...
@@ -5831,9 +5702,7 @@ static void genericZrangebyscoreCommand(redisClient *c, int justcount) {
...
@@ -5831,9 +5702,7 @@ static void genericZrangebyscoreCommand(redisClient *c, int justcount) {
if (limit == 0) break;
if (limit == 0) break;
if (!justcount) {
if (!justcount) {
ele = ln->obj;
ele = ln->obj;
addReplyBulkLen
(
c
,
ele
);
addReplyBulk(c,ele);
addReply
(
c
,
ele
);
addReply
(
c
,
shared
.
crlf
);
if (withscores)
if (withscores)
addReplyDouble(c,ln->score);
addReplyDouble(c,ln->score);
}
}
...
@@ -5862,80 +5731,62 @@ static void zcountCommand(redisClient *c) {
...
@@ -5862,80 +5731,62 @@ static void zcountCommand(redisClient *c) {
static void zcardCommand(redisClient *c) {
static void zcardCommand(redisClient *c) {
robj *o;
robj *o;
zset *zs;
zset *zs;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
if
(
o
==
NULL
)
{
checkType(c,o,REDIS_ZSET)) return;
addReply
(
c
,
shared
.
czero
);
return
;
zs = o->ptr;
}
else
{
addReplyUlong(c,zs->zsl->length);
if
(
o
->
type
!=
REDIS_ZSET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
zs
=
o
->
ptr
;
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%lu
\r\n
"
,
zs
->
zsl
->
length
));
}
}
}
}
static void zscoreCommand(redisClient *c) {
static void zscoreCommand(redisClient *c) {
robj *o;
robj *o;
zset *zs;
zset *zs;
dictEntry *de;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if
(
o
==
NULL
)
{
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_ZSET)) return;
zs = o->ptr;
de = dictFind(zs->dict,c->argv[2]);
if (!de) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
return
;
} else {
} else {
if
(
o
->
type
!=
REDIS_ZSET
)
{
double *score = dictGetEntryVal(de);
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
dictEntry
*
de
;
zs
=
o
->
ptr
;
de
=
dictFind
(
zs
->
dict
,
c
->
argv
[
2
]);
if
(
!
de
)
{
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
double
*
score
=
dictGetEntryVal
(
de
);
addReplyDouble
(
c
,
*
score
);
addReplyDouble(c,*score);
}
}
}
}
}
}
static void zrankGenericCommand(redisClient *c, int reverse) {
static void zrankGenericCommand(redisClient *c, int reverse) {
robj *o;
robj *o;
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
zset *zs;
if
(
o
==
NULL
)
{
zskiplist *zsl;
dictEntry *de;
unsigned long rank;
double *score;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
checkType(c,o,REDIS_ZSET)) return;
zs = o->ptr;
zsl = zs->zsl;
de = dictFind(zs->dict,c->argv[2]);
if (!de) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
return;
return;
}
}
if
(
o
->
type
!=
REDIS_ZSET
)
{
addReply
(
c
,
shared
.
wrongtypeerr
);
}
else
{
zset
*
zs
=
o
->
ptr
;
zskiplist
*
zsl
=
zs
->
zsl
;
dictEntry
*
de
;
unsigned
long
rank
;
de
=
dictFind
(
zs
->
dict
,
c
->
argv
[
2
]);
score = dictGetEntryVal(de);
if
(
!
de
)
{
rank = zslGetRank(zsl, *score, c->argv[2]);
addReply
(
c
,
shared
.
nullbulk
);
if (rank) {
return
;
if (reverse) {
}
addReplyLong(c, zsl->length - rank);
double
*
score
=
dictGetEntryVal
(
de
);
rank
=
zslGetRank
(
zsl
,
*
score
,
c
->
argv
[
2
]);
if
(
rank
)
{
if
(
reverse
)
{
addReplyLong
(
c
,
zsl
->
length
-
rank
);
}
else
{
addReplyLong
(
c
,
rank
-
1
);
}
} else {
} else {
addReply
(
c
,
shared
.
nullbulk
);
addReply
Long(c, rank-1
);
}
}
} else {
addReply(c,shared.nullbulk);
}
}
}
}
...
@@ -6006,78 +5857,61 @@ static void hsetCommand(redisClient *c) {
...
@@ -6006,78 +5857,61 @@ static void hsetCommand(redisClient *c) {
}
}
static void hgetCommand(redisClient *c) {
static void hgetCommand(redisClient *c) {
robj
*
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
])
;
robj *o;
if
(
o
==
NULL
)
{
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
addReply
(
c
,
shared
.
nullbulk
);
checkType(c,o,REDIS_HASH)) return;
return
;
}
else
{
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
if
(
o
->
type
!=
REDIS_HASH
)
{
unsigned char *zm = o->ptr;
addReply
(
c
,
shared
.
wrongtypeerr
);
unsigned char *val;
unsigned int vlen;
if (zipmapGet(zm,c->argv[2]->ptr,sdslen(c->argv[2]->ptr), &val,&vlen)) {
addReplySds(c,sdscatprintf(sdsempty(),"$%u\r\n", vlen));
addReplySds(c,sdsnewlen(val,vlen));
addReply(c,shared.crlf);
return;
} else {
addReply(c,shared.nullbulk);
return;
return;
}
}
} else {
struct dictEntry *de;
if
(
o
->
encoding
==
REDIS_ENCODING_ZIPMAP
)
{
de = dictFind(o->ptr,c->argv[2]);
unsigned
char
*
zm
=
o
->
ptr
;
if (de == NULL) {
unsigned
char
*
val
;
addReply(c,shared.nullbulk);
unsigned
int
vlen
;
if
(
zipmapGet
(
zm
,
c
->
argv
[
2
]
->
ptr
,
sdslen
(
c
->
argv
[
2
]
->
ptr
),
&
val
,
&
vlen
))
{
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
"$%u
\r\n
"
,
vlen
));
addReplySds
(
c
,
sdsnewlen
(
val
,
vlen
));
addReply
(
c
,
shared
.
crlf
);
return
;
}
else
{
addReply
(
c
,
shared
.
nullbulk
);
return
;
}
} else {
} else {
struct
dictEntry
*
de
;
robj *e =
dict
Get
Entry
Val(
de
)
;
de
=
dictFind
(
o
->
ptr
,
c
->
argv
[
2
]);
addReplyBulk(c,e);
if
(
de
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
}
else
{
robj
*
e
=
dictGetEntryVal
(
de
);
addReplyBulkLen
(
c
,
e
);
addReply
(
c
,
e
);
addReply
(
c
,
shared
.
crlf
);
}
}
}
}
}
}
}
static void hdelCommand(redisClient *c) {
static void hdelCommand(redisClient *c) {
robj
*
o
=
lookupKeyWrite
(
c
->
db
,
c
->
argv
[
1
]);
robj *o;
int deleted = 0;
if
(
o
==
NULL
)
{
addReply
(
c
,
shared
.
czero
);
return
;
}
else
{
int
deleted
=
0
;
if
(
o
->
type
!=
REDIS_HASH
)
{
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
addReply
(
c
,
shared
.
wrongtypeerr
);
checkType(c,o,REDIS_HASH)) return;
return
;
}
if
(
o
->
encoding
==
REDIS_ENCODING_ZIPMAP
)
{
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
o
->
ptr
=
zipmapDel
((
unsigned
char
*
)
o
->
ptr
,
o->ptr = zipmapDel((unsigned char*) o->ptr,
(
unsigned
char
*
)
c
->
argv
[
2
]
->
ptr
,
(unsigned char*) c->argv[2]->ptr,
sdslen
(
c
->
argv
[
2
]
->
ptr
),
&
deleted
);
sdslen(c->argv[2]->ptr), &deleted);
}
else
{
} else {
deleted
=
dictDelete
((
dict
*
)
o
->
ptr
,
c
->
argv
[
2
])
==
DICT_OK
;
deleted = dictDelete((dict*)o->ptr,c->argv[2]) == DICT_OK;
}
addReply
(
c
,
deleted
?
shared
.
cone
:
shared
.
czero
);
}
}
addReply(c,deleted ? shared.cone : shared.czero);
}
}
static void hlenCommand(redisClient *c) {
static void hlenCommand(redisClient *c) {
robj *o;
robj *o;
unsigned long len;
unsigned long len;
if
((
o
=
lookupKey
Write
OrReply
(
c
,
c
->
argv
[
1
],
shared
.
czero
))
==
NULL
||
if ((o = lookupKey
Read
OrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,o,REDIS_HASH)) return;
checkType(c,o,REDIS_HASH)) return;
len = (o->encoding == REDIS_ENCODING_ZIPMAP) ?
len = (o->encoding == REDIS_ENCODING_ZIPMAP) ?
...
@@ -6410,11 +6244,7 @@ static void sortCommand(redisClient *c) {
...
@@ -6410,11 +6244,7 @@ static void sortCommand(redisClient *c) {
listNode *ln;
listNode *ln;
listIter li;
listIter li;
if
(
!
getop
)
{
if (!getop) addReplyBulk(c,vector[j].obj);
addReplyBulkLen
(
c
,
vector
[
j
].
obj
);
addReply
(
c
,
vector
[
j
].
obj
);
addReply
(
c
,
shared
.
crlf
);
}
listRewind(operations,&li);
listRewind(operations,&li);
while((ln = listNext(&li))) {
while((ln = listNext(&li))) {
redisSortOperation *sop = ln->value;
redisSortOperation *sop = ln->value;
...
@@ -6425,9 +6255,7 @@ static void sortCommand(redisClient *c) {
...
@@ -6425,9 +6255,7 @@ static void sortCommand(redisClient *c) {
if (!val || val->type != REDIS_STRING) {
if (!val || val->type != REDIS_STRING) {
addReply(c,shared.nullbulk);
addReply(c,shared.nullbulk);
} else {
} else {
addReplyBulkLen
(
c
,
val
);
addReplyBulk(c,val);
addReply
(
c
,
val
);
addReply
(
c
,
shared
.
crlf
);
}
}
} else {
} else {
redisAssert(sop->type == REDIS_SORT_GET); /* always fails */
redisAssert(sop->type == REDIS_SORT_GET); /* always fails */
...
@@ -6945,12 +6773,8 @@ static int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
...
@@ -6945,12 +6773,8 @@ static int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
receiver = ln->value;
receiver = ln->value;
addReplySds(receiver,sdsnew("*2\r\n"));
addReplySds(receiver,sdsnew("*2\r\n"));
addReplyBulkLen
(
receiver
,
key
);
addReplyBulk(receiver,key);
addReply
(
receiver
,
key
);
addReplyBulk(receiver,ele);
addReply
(
receiver
,
shared
.
crlf
);
addReplyBulkLen
(
receiver
,
ele
);
addReply
(
receiver
,
ele
);
addReply
(
receiver
,
shared
.
crlf
);
unblockClientWaitingData(receiver);
unblockClientWaitingData(receiver);
return 1;
return 1;
}
}
...
@@ -6989,9 +6813,7 @@ static void blockingPopGenericCommand(redisClient *c, int where) {
...
@@ -6989,9 +6813,7 @@ static void blockingPopGenericCommand(redisClient *c, int where) {
* for us. If this souds like an hack to you it's just
* for us. If this souds like an hack to you it's just
* because it is... */
* because it is... */
addReplySds(c,sdsnew("*2\r\n"));
addReplySds(c,sdsnew("*2\r\n"));
addReplyBulkLen
(
c
,
argv
[
1
]);
addReplyBulk(c,argv[1]);
addReply
(
c
,
argv
[
1
]);
addReply
(
c
,
shared
.
crlf
);
popGenericCommand(c,where);
popGenericCommand(c,where);
/* Fix the client structure with the original stuff */
/* Fix the client structure with the original stuff */
...
...
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