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