Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
hanoi2005
redis
提交
5d1b4fb6
R
redis
项目概览
hanoi2005
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5d1b4fb6
编写于
3月 09, 2011
作者:
P
Pieter Noordhuis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support dual encoding for ZRANGE
上级
0f23eb3b
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
96 addition
and
29 deletion
+96
-29
src/t_zset.c
src/t_zset.c
+96
-29
未找到文件。
src/t_zset.c
浏览文件 @
5d1b4fb6
...
...
@@ -666,6 +666,22 @@ unsigned long zzlDeleteRangeByScore(robj *zobj, zrangespec range) {
return
deleted
;
}
/*-----------------------------------------------------------------------------
* Common sorted set API
*----------------------------------------------------------------------------*/
int
zsLength
(
robj
*
zobj
)
{
int
length
=
-
1
;
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
length
=
zzlLength
(
zobj
);
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_RAW
)
{
length
=
((
zset
*
)
zobj
->
ptr
)
->
zsl
->
length
;
}
else
{
redisPanic
(
"Unknown sorted set encoding"
);
}
return
length
;
}
/*-----------------------------------------------------------------------------
* Sorted set commands
*----------------------------------------------------------------------------*/
...
...
@@ -1135,16 +1151,13 @@ void zinterstoreCommand(redisClient *c) {
}
void
zrangeGenericCommand
(
redisClient
*
c
,
int
reverse
)
{
robj
*
o
;
robj
*
key
=
c
->
argv
[
1
];
robj
*
zobj
;
int
withscores
=
0
;
long
start
;
long
end
;
int
withscores
=
0
;
int
llen
;
int
rangelen
,
j
;
zset
*
zsetobj
;
zskiplist
*
zsl
;
zskiplistNode
*
ln
;
robj
*
ele
;
int
rangelen
;
if
((
getLongFromObjectOrReply
(
c
,
c
->
argv
[
2
],
&
start
,
NULL
)
!=
REDIS_OK
)
||
(
getLongFromObjectOrReply
(
c
,
c
->
argv
[
3
],
&
end
,
NULL
)
!=
REDIS_OK
))
return
;
...
...
@@ -1156,13 +1169,11 @@ void zrangeGenericCommand(redisClient *c, int reverse) {
return
;
}
if
((
o
=
lookupKeyReadOrReply
(
c
,
c
->
argv
[
1
],
shared
.
emptymultibulk
))
==
NULL
||
checkType
(
c
,
o
,
REDIS_ZSET
))
return
;
zsetobj
=
o
->
ptr
;
zsl
=
zsetobj
->
zsl
;
llen
=
zsl
->
length
;
if
((
zobj
=
lookupKeyReadOrReply
(
c
,
key
,
shared
.
emptymultibulk
))
==
NULL
||
checkType
(
c
,
zobj
,
REDIS_ZSET
))
return
;
/* convert negative indexes */
/* Sanitize indexes. */
llen
=
zsLength
(
zobj
);
if
(
start
<
0
)
start
=
llen
+
start
;
if
(
end
<
0
)
end
=
llen
+
end
;
if
(
start
<
0
)
start
=
0
;
...
...
@@ -1176,23 +1187,79 @@ void zrangeGenericCommand(redisClient *c, int reverse) {
if
(
end
>=
llen
)
end
=
llen
-
1
;
rangelen
=
(
end
-
start
)
+
1
;
/* check if starting point is trivial, before searching
* the element in log(N) time */
if
(
reverse
)
{
ln
=
start
==
0
?
zsl
->
tail
:
zslGetElementByRank
(
zsl
,
llen
-
start
);
}
else
{
ln
=
start
==
0
?
zsl
->
header
->
level
[
0
].
forward
:
zslGetElementByRank
(
zsl
,
start
+
1
);
}
/* Return the result in form of a multi-bulk reply */
addReplyMultiBulkLen
(
c
,
withscores
?
(
rangelen
*
2
)
:
rangelen
);
for
(
j
=
0
;
j
<
rangelen
;
j
++
)
{
ele
=
ln
->
obj
;
addReplyBulk
(
c
,
ele
);
if
(
withscores
)
addReplyDouble
(
c
,
ln
->
score
);
ln
=
reverse
?
ln
->
backward
:
ln
->
level
[
0
].
forward
;
addReplyMultiBulkLen
(
c
,
withscores
?
(
rangelen
*
2
)
:
rangelen
);
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
eptr
,
*
sptr
;
unsigned
char
*
vstr
;
unsigned
int
vlen
;
long
long
vlong
;
if
(
reverse
)
eptr
=
ziplistIndex
(
zl
,
-
2
-
(
2
*
start
));
else
eptr
=
ziplistIndex
(
zl
,
2
*
start
);
while
(
rangelen
--
)
{
redisAssert
(
eptr
!=
NULL
);
redisAssert
(
ziplistGet
(
eptr
,
&
vstr
,
&
vlen
,
&
vlong
));
if
(
vstr
==
NULL
)
addReplyBulkLongLong
(
c
,
vlong
);
else
addReplyBulkCBuffer
(
c
,
vstr
,
vlen
);
if
(
withscores
)
{
sptr
=
ziplistNext
(
zl
,
eptr
);
redisAssert
(
sptr
!=
NULL
);
addReplyDouble
(
c
,
zzlGetScore
(
sptr
));
}
if
(
reverse
)
{
/* Move to previous element by moving to the score of previous
* element. When NULL, we know there also is no element. */
sptr
=
ziplistPrev
(
zl
,
eptr
);
if
(
sptr
!=
NULL
)
{
eptr
=
ziplistPrev
(
zl
,
sptr
);
redisAssert
(
eptr
!=
NULL
);
}
else
{
eptr
=
NULL
;
}
}
else
{
sptr
=
ziplistNext
(
zl
,
eptr
);
redisAssert
(
sptr
!=
NULL
);
eptr
=
ziplistNext
(
zl
,
sptr
);
}
}
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_RAW
)
{
zset
*
zs
=
zobj
->
ptr
;
zskiplist
*
zsl
=
zs
->
zsl
;
zskiplistNode
*
ln
;
robj
*
ele
;
/* Check if starting point is trivial, before doing log(N) lookup. */
if
(
reverse
)
{
ln
=
zsl
->
tail
;
if
(
start
>
0
)
ln
=
zslGetElementByRank
(
zsl
,
llen
-
start
);
}
else
{
ln
=
zsl
->
header
->
level
[
0
].
forward
;
if
(
start
>
0
)
ln
=
zslGetElementByRank
(
zsl
,
start
+
1
);
}
while
(
rangelen
--
)
{
redisAssert
(
ln
!=
NULL
);
ele
=
ln
->
obj
;
addReplyBulk
(
c
,
ele
);
if
(
withscores
)
addReplyDouble
(
c
,
ln
->
score
);
ln
=
reverse
?
ln
->
backward
:
ln
->
level
[
0
].
forward
;
}
}
else
{
redisPanic
(
"Unknown sorted set encoding"
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录