Skip to content
This repository has been archived by the owner on Feb 21, 2023. It is now read-only.

Commit

Permalink
Added ZREVRANGEBYLEX command
Browse files Browse the repository at this point in the history
  • Loading branch information
marijngiesen authored and popravich committed Jun 21, 2017
1 parent bab6a0b commit d93e25d
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
33 changes: 33 additions & 0 deletions aioredis/commands/sorted_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,39 @@ def zrevrangebyscore(self, key, max=float('inf'), min=float('-inf'),
return wait_convert(fut, pairs_int_or_float)
return fut

def zrevrangebylex(self, key, min=b'-', max=b'+', include_min=True,
include_max=True, offset=None, count=None):
"""Return a range of members in a sorted set, by lexicographical range from high to low.
:raises TypeError: if min is not bytes
:raises TypeError: if max is not bytes
:raises TypeError: if both offset and count are not specified
:raises TypeError: if offset is not bytes
:raises TypeError: if count is not bytes
"""
if not isinstance(min, bytes): # FIXME
raise TypeError("min argument must be bytes")
if not isinstance(max, bytes): # FIXME
raise TypeError("max argument must be bytes")
if not min == b'-':
min = (b'[' if include_min else b'(') + min
if not max == b'+':
max = (b'[' if include_max else b'(') + max

if (offset is not None and count is None) or \
(count is not None and offset is None):
raise TypeError("offset and count must both be specified")
if offset is not None and not isinstance(offset, int):
raise TypeError("offset argument must be int")
if count is not None and not isinstance(count, int):
raise TypeError("count argument must be int")

args = []
if offset is not None and count is not None:
args.extend([b'LIMIT', offset, count])

return self.execute(b'ZREVRANGEBYLEX', key, max, min, *args)

def zrevrank(self, key, member):
"""Determine the index of a member in a sorted set, with
scores ordered from high to low.
Expand Down
44 changes: 44 additions & 0 deletions tests/sorted_set_commands_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,50 @@ def test_zrevrangebyscore(redis):
yield from redis.zrevrangebyscore(key, 1, 7, offset=1, count='one')


@pytest.redis_version(
2, 8, 9, reason='ZRANGEBYLEX is available since redis>=2.8.9')
@pytest.mark.run_loop
def test_zrevrangebylex(redis):
key = b'key:zrevrangebylex'
scores = [0]*5
members = [b'a', b'b', b'c', b'd', b'e']
rev_members = members[::-1]
pairs = list(itertools.chain(*zip(scores, members)))

res = yield from redis.zadd(key, *pairs)
assert res == 5
res = yield from redis.zrevrangebylex(key)
assert res == rev_members
res = yield from redis.zrevrangebylex(key, min=b'-', max=b'd')
assert res == rev_members[1:]
res = yield from redis.zrevrangebylex(key, min=b'a', max=b'e',
include_min=False,
include_max=False)
assert res == rev_members[1:-1]
res = yield from redis.zrevrangebylex(key, min=b'x', max=b'z')
assert res == []
res = yield from redis.zrevrangebylex(key, min=b'e', max=b'a')
assert res == []
res = yield from redis.zrevrangebylex(key, offset=1, count=2)
assert res == rev_members[1:3]
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(None, b'a', b'e')
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(key, 10, b'e')
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(key, b'a', 20)
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(key, b'a', b'e', offset=1)
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(key, b'a', b'e', count=1)
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(key, b'a', b'e',
offset='one', count=1)
with pytest.raises(TypeError):
yield from redis.zrevrangebylex(key, b'a', b'e',
offset=1, count='one')


@pytest.redis_version(2, 8, 0, reason='ZSCAN is available since redis>=2.8.0')
@pytest.mark.run_loop
def test_zscan(redis):
Expand Down

0 comments on commit d93e25d

Please sign in to comment.