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
You need to sign in or sign up before continuing.
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