Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
别团等shy哥发育
redis
提交
aff255c8
R
redis
项目概览
别团等shy哥发育
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
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,发现更多精彩内容 >>
提交
aff255c8
编写于
3月 09, 2011
作者:
P
Pieter Noordhuis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support dual encoding for ZRANGEBYSCORE et al
上级
4c5f0966
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
114 addition
and
45 deletion
+114
-45
src/t_zset.c
src/t_zset.c
+114
-45
未找到文件。
src/t_zset.c
浏览文件 @
aff255c8
...
...
@@ -1318,10 +1318,8 @@ void zrevrangeCommand(redisClient *c) {
* If "justcount", only the number of elements in the range is returned. */
void
genericZrangebyscoreCommand
(
redisClient
*
c
,
int
reverse
,
int
justcount
)
{
zrangespec
range
;
robj
*
o
,
*
emptyreply
;
zset
*
zsetobj
;
zskiplist
*
zsl
;
zskiplistNode
*
ln
;
robj
*
key
=
c
->
argv
[
1
];
robj
*
emptyreply
,
*
zobj
;
int
offset
=
0
,
limit
=
-
1
;
int
withscores
=
0
;
unsigned
long
rangelen
=
0
;
...
...
@@ -1365,17 +1363,86 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
/* Ok, lookup the key and get the range */
emptyreply
=
justcount
?
shared
.
czero
:
shared
.
emptymultibulk
;
if
((
o
=
lookupKeyReadOrReply
(
c
,
c
->
argv
[
1
],
emptyreply
))
==
NULL
||
checkType
(
c
,
o
,
REDIS_ZSET
))
return
;
zsetobj
=
o
->
ptr
;
zsl
=
zsetobj
->
zsl
;
if
((
zobj
=
lookupKeyReadOrReply
(
c
,
key
,
emptyreply
))
==
NULL
||
checkType
(
c
,
zobj
,
REDIS_ZSET
))
return
;
if
(
zobj
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
unsigned
char
*
zl
=
zobj
->
ptr
;
unsigned
char
*
eptr
,
*
sptr
;
unsigned
char
*
vstr
;
unsigned
int
vlen
;
long
long
vlong
;
double
score
;
/* If reversed, get the last node in range as starting point. */
if
(
reverse
)
eptr
=
zzlLastInRange
(
zobj
,
range
);
else
eptr
=
zzlFirstInRange
(
zobj
,
range
);
/* No "first" element in the specified interval. */
if
(
eptr
==
NULL
)
{
addReply
(
c
,
emptyreply
);
return
;
}
/* Get score pointer for the first element. */
redisAssert
(
eptr
!=
NULL
);
sptr
=
ziplistNext
(
zl
,
eptr
);
/* We don't know in advance how many matching elements there are in the
* list, so we push this object that will represent the multi-bulk
* length in the output buffer, and will "fix" it later */
if
(
!
justcount
)
replylen
=
addDeferredMultiBulkLength
(
c
);
/* If there is an offset, just traverse the number of elements without
* checking the score because that is done in the next loop. */
while
(
eptr
&&
offset
--
)
if
(
reverse
)
zzlPrev
(
zl
,
&
eptr
,
&
sptr
);
else
zzlNext
(
zl
,
&
eptr
,
&
sptr
);
while
(
eptr
&&
limit
--
)
{
score
=
zzlGetScore
(
sptr
);
/* Abort when the node is no longer in range. */
if
(
reverse
)
{
ln
=
zslLastInRange
(
zsl
,
range
)
;
if
(
!
zslValueGteMin
(
score
,
&
range
))
break
;
}
else
{
ln
=
zslFirstInRange
(
zsl
,
range
);
if
(
!
zslValueLteMax
(
score
,
&
range
))
break
;
}
/* Do our magic */
rangelen
++
;
if
(
!
justcount
)
{
redisAssert
(
ziplistGet
(
eptr
,
&
vstr
,
&
vlen
,
&
vlong
));
if
(
vstr
==
NULL
)
addReplyBulkLongLong
(
c
,
vlong
);
else
addReplyBulkCBuffer
(
c
,
vstr
,
vlen
);
if
(
withscores
)
addReplyDouble
(
c
,
score
);
}
/* Move to next node */
if
(
reverse
)
zzlPrev
(
zl
,
&
eptr
,
&
sptr
);
else
zzlNext
(
zl
,
&
eptr
,
&
sptr
);
}
}
else
if
(
zobj
->
encoding
==
REDIS_ENCODING_RAW
)
{
zset
*
zs
=
zobj
->
ptr
;
zskiplist
*
zsl
=
zs
->
zsl
;
zskiplistNode
*
ln
;
/* If reversed, get the last node in range as starting point. */
if
(
reverse
)
ln
=
zslLastInRange
(
zsl
,
range
);
else
ln
=
zslFirstInRange
(
zsl
,
range
);
/* No "first" element in the specified interval. */
if
(
ln
==
NULL
)
{
...
...
@@ -1384,16 +1451,15 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
}
/* We don't know in advance how many matching elements there are in the
* list, so we push this object that will represent the multi-bulk length
*
in the output buffer, and will "fix" it later */
* list, so we push this object that will represent the multi-bulk
* length
in the output buffer, and will "fix" it later */
if
(
!
justcount
)
replylen
=
addDeferredMultiBulkLength
(
c
);
/* If there is an offset, just traverse the number of elements without
* checking the score because that is done in the next loop. */
while
(
ln
&&
offset
--
)
{
while
(
ln
&&
offset
--
)
ln
=
reverse
?
ln
->
backward
:
ln
->
level
[
0
].
forward
;
}
while
(
ln
&&
limit
--
)
{
/* Abort when the node is no longer in range. */
...
...
@@ -1414,12 +1480,15 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
/* Move to next node */
ln
=
reverse
?
ln
->
backward
:
ln
->
level
[
0
].
forward
;
}
}
else
{
redisPanic
(
"Unknown sorted set encoding"
);
}
if
(
justcount
)
{
addReplyLongLong
(
c
,(
long
)
rangelen
);
}
else
{
setDeferredMultiBulkLength
(
c
,
replylen
,
withscores
?
(
rangelen
*
2
)
:
rangelen
);
if
(
withscores
)
rangelen
*=
2
;
setDeferredMultiBulkLength
(
c
,
replylen
,
rangelen
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录