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