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
2b04f86a
Commit
2b04f86a
authored
Apr 21, 2016
by
antirez
Browse files
Modules: zset lex iterator #1.
parent
083f5277
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/module.c
View file @
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
View file @
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
View file @
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
||
...
...
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