Skip to content

Commit

Permalink
MINID and LIMIT support for xtrim (#1508)
Browse files Browse the repository at this point in the history
  • Loading branch information
chayim committed Aug 15, 2021
1 parent 37e7c09 commit e498182
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
24 changes: 21 additions & 3 deletions redis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2979,17 +2979,35 @@ def xrevrange(self, name, max='+', min='-', count=None):

return self.execute_command('XREVRANGE', name, *pieces)

def xtrim(self, name, maxlen, approximate=True):
def xtrim(self, name, maxlen=None, approximate=True, minid=None,
limit=None):
"""
Trims old messages from a stream.
name: name of the stream.
maxlen: truncate old stream messages beyond this size
approximate: actual stream length may be slightly more than maxlen
minin: the minimum id in the stream to query
limit: specifies the maximum number of entries to retrieve
"""
pieces = [b'MAXLEN']
pieces = []
if maxlen is not None and minid is not None:
raise DataError("Only one of ```maxlen``` or ```minid```",
"may be specified")

if maxlen is not None:
pieces.append(b'MAXLEN')
if minid is not None:
pieces.append(b'MINID')
if approximate:
pieces.append(b'~')
pieces.append(maxlen)
if maxlen is not None:
pieces.append(maxlen)
if minid is not None:
pieces.append(minid)
if limit is not None:
pieces.append(b"LIMIT")
pieces.append(limit)

return self.execute_command('XTRIM', name, *pieces)

# SORTED SET COMMANDS
Expand Down
41 changes: 41 additions & 0 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2927,6 +2927,47 @@ def test_xtrim(self, r):
# 1 message is trimmed
assert r.xtrim(stream, 3, approximate=False) == 1

@skip_if_server_version_lt('6.2.4')
def test_xtrim_minlen_and_length_args(self, r):
stream = 'stream'

r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})

# Future self: No limits without approximate, according to the api
with pytest.raises(redis.ResponseError):
assert r.xtrim(stream, 3, approximate=False, limit=2)

# maxlen with a limit
assert r.xtrim(stream, 3, approximate=True, limit=2) == 0
r.delete(stream)

with pytest.raises(redis.DataError):
assert r.xtrim(stream, maxlen=3, minid="sometestvalue")

# minid with a limit
m1 = r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
assert r.xtrim(stream, None, approximate=True, minid=m1, limit=3) == 0

# pure minid
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
m4 = r.xadd(stream, {'foo': 'bar'})
assert r.xtrim(stream, None, approximate=False, minid=m4) == 7

# minid approximate
r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
m3 = r.xadd(stream, {'foo': 'bar'})
r.xadd(stream, {'foo': 'bar'})
assert r.xtrim(stream, None, approximate=True, minid=m3) == 0

def test_bitfield_operations(self, r):
# comments show affected bits
bf = r.bitfield('a')
Expand Down

0 comments on commit e498182

Please sign in to comment.