Skip to content

Commit

Permalink
Merge pull request #1170 from wcmonty/wm/add_minid_option_to_xtrim
Browse files Browse the repository at this point in the history
[Redis 6.2] Add MINID and LIMIT options to xtrim
  • Loading branch information
byroot authored Dec 4, 2022
2 parents 3c42db6 + e76e1cb commit 5a9fb00
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
28 changes: 22 additions & 6 deletions lib/redis/commands/streams.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,30 @@ def xadd(key, entry, approximate: nil, maxlen: nil, nomkstream: nil, id: '*')
# redis.xtrim('mystream', 1000)
# @example With options
# redis.xtrim('mystream', 1000, approximate: true)
#
# @param key [String] the stream key
# @param mexlen [Integer] max length of entries
# @param approximate [Boolean] whether to add `~` modifier of maxlen or not
# @example With strategy
# redis.xtrim('mystream', '1-0', strategy: 'MINID')
#
# @overload xtrim(key, maxlen, strategy: 'MAXLEN', approximate: true)
# @param key [String] the stream key
# @param maxlen [Integer] max length of entries
# @param strategy [String] the limit strategy, must be MAXLEN
# @param approximate [Boolean] whether to add `~` modifier of maxlen or not
# @param limit [Integer] maximum count of entries to be evicted
# @overload xtrim(key, minid, strategy: 'MINID', approximate: true)
# @param key [String] the stream key
# @param minid [String] minimum id of entries
# @param strategy [String] the limit strategy, must be MINID
# @param approximate [Boolean] whether to add `~` modifier of minid or not
# @param limit [Integer] maximum count of entries to be evicted
#
# @return [Integer] the number of entries actually deleted
def xtrim(key, maxlen, approximate: false)
args = [:xtrim, key, 'MAXLEN', (approximate ? '~' : nil), maxlen].compact
def xtrim(key, len_or_id, strategy: 'MAXLEN', approximate: false, limit: nil)
strategy = strategy.to_s.upcase

args = [:xtrim, key, strategy]
args << '~' if approximate
args << len_or_id
args.concat(['LIMIT', limit]) if limit
send_command(args)
end

Expand Down
58 changes: 56 additions & 2 deletions test/lint/streams.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,73 @@ def test_xtrim_with_approximate_option
assert_equal 0, redis.xtrim('s1', 2, approximate: true)
end

def test_xtrim_with_limit_option
omit_version('6.2.0')

begin
original = redis.config(:get, 'stream-node-max-entries')['stream-node-max-entries']
redis.config(:set, 'stream-node-max-entries', 1)

redis.xadd('s1', { f: 'v1' })
redis.xadd('s1', { f: 'v2' })
redis.xadd('s1', { f: 'v3' })
redis.xadd('s1', { f: 'v4' })

assert_equal 1, redis.xtrim('s1', 0, approximate: true, limit: 1)
error = assert_raises(Redis::CommandError) { redis.xtrim('s1', 0, limit: 1) }
assert_equal "ERR syntax error, LIMIT cannot be used without the special ~ option", error.message
ensure
redis.config(:set, 'stream-node-max-entries', original)
end
end

def test_xtrim_with_maxlen_strategy
redis.xadd('s1', { f: 'v1' }, id: '0-1')
redis.xadd('s1', { f: 'v1' }, id: '0-2')
redis.xadd('s1', { f: 'v1' }, id: '1-0')
redis.xadd('s1', { f: 'v1' }, id: '1-1')
assert_equal(2, redis.xtrim('s1', 2, strategy: 'MAXLEN'))
end

def test_xtrim_with_minid_strategy
omit_version('6.2.0')

redis.xadd('s1', { f: 'v1' }, id: '0-1')
redis.xadd('s1', { f: 'v1' }, id: '0-2')
redis.xadd('s1', { f: 'v1' }, id: '1-0')
redis.xadd('s1', { f: 'v1' }, id: '1-1')
assert_equal(2, redis.xtrim('s1', '1-0', strategy: 'MINID'))
end

def test_xtrim_with_approximate_minid_strategy
omit_version('6.2.0')

redis.xadd('s1', { f: 'v1' }, id: '0-1')
redis.xadd('s1', { f: 'v1' }, id: '0-2')
redis.xadd('s1', { f: 'v1' }, id: '1-0')
redis.xadd('s1', { f: 'v1' }, id: '1-1')
assert_equal(0, redis.xtrim('s1', '1-0', strategy: 'MINID', approximate: true))
end

def test_xtrim_with_invalid_strategy
omit_version('6.2.0')

redis.xadd('s1', { f: 'v1' })
error = assert_raises(Redis::CommandError) { redis.xtrim('s1', '1-0', strategy: '') }
assert_equal "ERR syntax error", error.message
end

def test_xtrim_with_not_existed_stream
assert_equal 0, redis.xtrim('not-existed-stream', 2)
end

def test_xtrim_with_invalid_arguments
if version >= '6.2'
assert_raises(Redis::CommandError) { redis.xtrim('', '') }
assert_raises(Redis::CommandError) { redis.xtrim(nil, nil) }
assert_equal 0, redis.xtrim('s1', 0)
assert_raises(Redis::CommandError) { redis.xtrim('s1', -1, approximate: true) }
else
assert_equal 0, redis.xtrim('', '')
assert_equal 0, redis.xtrim(nil, nil)
assert_equal 0, redis.xtrim('s1', 0)
assert_equal 0, redis.xtrim('s1', -1, approximate: true)
end
Expand Down

0 comments on commit 5a9fb00

Please sign in to comment.