Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Turbo码先生
redis
提交
2b04f86a
R
redis
项目概览
Turbo码先生
/
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,发现更多精彩内容 >>
提交
2b04f86a
编写于
4月 21, 2016
作者:
A
antirez
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Modules: zset lex iterator #1.
上级
083f5277
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
77 addition
and
4 deletion
+77
-4
src/module.c
src/module.c
+70
-2
src/server.h
src/server.h
+5
-0
src/t_zset.c
src/t_zset.c
+2
-2
未找到文件。
src/module.c
浏览文件 @
2b04f86a
...
...
@@ -1152,17 +1152,85 @@ int zsetInitScoreRange(RedisModuleKey *key, double min, double max, int minex, i
* range. Returns REDISMODULE_OK if the iterator was correctly initialized
* otherwise REDISMODULE_ERR is returned in the following conditions:
*
* 1. The value stored at key is not a sorted set or the key is empty. */
* 1. The value stored at key is not a sorted set or the key is empty.
*
* The range is specified according to the two double values 'min' and 'max'.
* Both can be infinite using the following two macros:
*
* REDISMODULE_POSITIVE_INFINITE for positive infinite value
* REDISMODULE_NEGATIVE_INFINITE for negative infinite value
*
* 'minex' and 'maxex' parameters, if true, respectively setup a range
* where the min and max value are exclusive (not included) instead of
* inclusive. */
int
RM_ZsetFirstInScoreRange
(
RedisModuleKey
*
key
,
double
min
,
double
max
,
int
minex
,
int
maxex
)
{
return
zsetInitScoreRange
(
key
,
min
,
max
,
minex
,
maxex
,
1
);
}
/* Exactly like RedisModule_ZsetFirstInScoreRange() but the last element of
* the range is se
eked
instead. */
* the range is se
lected for the start of the iteration
instead. */
int
RM_ZsetLastInScoreRange
(
RedisModuleKey
*
key
,
double
min
,
double
max
,
int
minex
,
int
maxex
)
{
return
zsetInitScoreRange
(
key
,
min
,
max
,
minex
,
maxex
,
0
);
}
/* Helper function for RM_ZsetFirstInLexRange() and RM_ZsetLastInLexRange().
* Setup the sorted set iteration according to the specified lexicographical
* range (see the functions calling it for more info). If 'first' is true the
* first element in the range is used as a starting point for the iterator
* otherwise the last. Return REDISMODULE_OK on success otherwise
* REDISMODULE_ERR.
*
* Note that this function takes 'min' and 'max' in the same form of the
* Redis ZRANGEBYLEX command. */
int
zsetInitLexRange
(
RedisModuleKey
*
key
,
RedisModuleString
*
min
,
RedisModuleString
*
max
,
int
first
)
{
if
(
!
key
->
value
||
key
->
value
->
type
!=
OBJ_ZSET
)
return
REDISMODULE_ERR
;
RM_ZsetRangeStop
(
key
);
key
->
ztype
=
REDISMODULE_ZSET_RANGE_LEX
;
key
->
zer
=
0
;
/* Setup the range structure used by the sorted set core implementation
* in order to seek at the specified element. */
zlexrangespec
*
zlrs
=
&
key
->
zlrs
;
if
(
zslParseLexRange
(
min
,
max
,
zlrs
)
==
C_ERR
)
return
REDISMODULE_ERR
;
if
(
key
->
value
->
encoding
==
OBJ_ENCODING_ZIPLIST
)
{
key
->
zcurrent
=
first
?
zzlFirstInLexRange
(
key
->
value
->
ptr
,
zlrs
)
:
zzlLastInLexRange
(
key
->
value
->
ptr
,
zlrs
);
}
else
if
(
key
->
value
->
encoding
==
OBJ_ENCODING_SKIPLIST
)
{
zset
*
zs
=
key
->
value
->
ptr
;
zskiplist
*
zsl
=
zs
->
zsl
;
key
->
zcurrent
=
first
?
zslFirstInLexRange
(
zsl
,
zlrs
)
:
zslLastInLexRange
(
zsl
,
zlrs
);
}
else
{
serverPanic
(
"Unsupported zset encoding"
);
}
if
(
key
->
zcurrent
==
NULL
)
key
->
zer
=
1
;
return
REDISMODULE_OK
;
}
/* Setup a sorted set iterator seeking the first element in the specified
* lexicographical range. Returns REDISMODULE_OK if the iterator was correctly
* initialized otherwise REDISMODULE_ERR is returned in the
* following conditions:
*
* 1. The value stored at key is not a sorted set or the key is empty.
* 2. The lexicographical range 'min' and 'max' format is invalid.
*
* 'min' and 'max' should be provided as two RedisModuleString objects
* in the same format as the parameters passed to the ZRANGEBYLEX command.
* The function does not take ownership of the objects, so they can be released
* ASAP after the iterator is setup. */
int
RM_ZsetFirstInLexRange
(
RedisModuleKey
*
key
,
RedisModuleString
*
min
,
RedisModuleString
*
max
)
{
return
zsetInitLexRange
(
key
,
min
,
max
,
1
);
}
/* Exactly like RedisModule_ZsetFirstInLexRange() but the last element of
* the range is selected for the start of the iteration instead. */
int
RM_ZsetLastInLexRange
(
RedisModuleKey
*
key
,
RedisModuleString
*
min
,
RedisModuleString
*
max
)
{
return
zsetInitLexRange
(
key
,
min
,
max
,
0
);
}
/* Return the current sorted set element of an active sorted set iterator
* or NULL if the range specified in the iterator does not include any
* element. */
...
...
src/server.h
浏览文件 @
2b04f86a
...
...
@@ -1348,6 +1348,11 @@ sds ziplistGetObject(unsigned char *sptr);
int
zslValueGteMin
(
double
value
,
zrangespec
*
spec
);
int
zslValueLteMax
(
double
value
,
zrangespec
*
spec
);
void
zslFreeLexRange
(
zlexrangespec
*
spec
);
int
zslParseLexRange
(
robj
*
min
,
robj
*
max
,
zlexrangespec
*
spec
);
unsigned
char
*
zzlFirstInLexRange
(
unsigned
char
*
zl
,
zlexrangespec
*
range
);
unsigned
char
*
zzlLastInLexRange
(
unsigned
char
*
zl
,
zlexrangespec
*
range
);
zskiplistNode
*
zslFirstInLexRange
(
zskiplist
*
zsl
,
zlexrangespec
*
range
);
zskiplistNode
*
zslLastInLexRange
(
zskiplist
*
zsl
,
zlexrangespec
*
range
);
/* Core functions */
int
freeMemoryIfNeeded
(
void
);
...
...
src/t_zset.c
浏览文件 @
2b04f86a
...
...
@@ -549,12 +549,12 @@ void zslFreeLexRange(zlexrangespec *spec) {
spec
->
max
!=
shared
.
maxstring
)
sdsfree
(
spec
->
max
);
}
/* Populate the rangespec according to the objects min and max.
/* Populate the
lex
rangespec according to the objects min and max.
*
* Return C_OK on success. On error C_ERR is returned.
* When OK is returned the structure must be freed with zslFreeLexRange(),
* otherwise no release is needed. */
static
int
zslParseLexRange
(
robj
*
min
,
robj
*
max
,
zlexrangespec
*
spec
)
{
int
zslParseLexRange
(
robj
*
min
,
robj
*
max
,
zlexrangespec
*
spec
)
{
/* The range can't be valid if objects are integer encoded.
* Every item must start with ( or [. */
if
(
min
->
encoding
==
OBJ_ENCODING_INT
||
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录