Skip to content

Commit 5a9fb00

Browse files
authored
Merge pull request #1170 from wcmonty/wm/add_minid_option_to_xtrim
[Redis 6.2] Add MINID and LIMIT options to xtrim
2 parents 3c42db6 + e76e1cb commit 5a9fb00

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

lib/redis/commands/streams.rb

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,30 @@ def xadd(key, entry, approximate: nil, maxlen: nil, nomkstream: nil, id: '*')
6565
# redis.xtrim('mystream', 1000)
6666
# @example With options
6767
# redis.xtrim('mystream', 1000, approximate: true)
68-
#
69-
# @param key [String] the stream key
70-
# @param mexlen [Integer] max length of entries
71-
# @param approximate [Boolean] whether to add `~` modifier of maxlen or not
68+
# @example With strategy
69+
# redis.xtrim('mystream', '1-0', strategy: 'MINID')
70+
#
71+
# @overload xtrim(key, maxlen, strategy: 'MAXLEN', approximate: true)
72+
# @param key [String] the stream key
73+
# @param maxlen [Integer] max length of entries
74+
# @param strategy [String] the limit strategy, must be MAXLEN
75+
# @param approximate [Boolean] whether to add `~` modifier of maxlen or not
76+
# @param limit [Integer] maximum count of entries to be evicted
77+
# @overload xtrim(key, minid, strategy: 'MINID', approximate: true)
78+
# @param key [String] the stream key
79+
# @param minid [String] minimum id of entries
80+
# @param strategy [String] the limit strategy, must be MINID
81+
# @param approximate [Boolean] whether to add `~` modifier of minid or not
82+
# @param limit [Integer] maximum count of entries to be evicted
7283
#
7384
# @return [Integer] the number of entries actually deleted
74-
def xtrim(key, maxlen, approximate: false)
75-
args = [:xtrim, key, 'MAXLEN', (approximate ? '~' : nil), maxlen].compact
85+
def xtrim(key, len_or_id, strategy: 'MAXLEN', approximate: false, limit: nil)
86+
strategy = strategy.to_s.upcase
87+
88+
args = [:xtrim, key, strategy]
89+
args << '~' if approximate
90+
args << len_or_id
91+
args.concat(['LIMIT', limit]) if limit
7692
send_command(args)
7793
end
7894

test/lint/streams.rb

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,73 @@ def test_xtrim_with_approximate_option
121121
assert_equal 0, redis.xtrim('s1', 2, approximate: true)
122122
end
123123

124+
def test_xtrim_with_limit_option
125+
omit_version('6.2.0')
126+
127+
begin
128+
original = redis.config(:get, 'stream-node-max-entries')['stream-node-max-entries']
129+
redis.config(:set, 'stream-node-max-entries', 1)
130+
131+
redis.xadd('s1', { f: 'v1' })
132+
redis.xadd('s1', { f: 'v2' })
133+
redis.xadd('s1', { f: 'v3' })
134+
redis.xadd('s1', { f: 'v4' })
135+
136+
assert_equal 1, redis.xtrim('s1', 0, approximate: true, limit: 1)
137+
error = assert_raises(Redis::CommandError) { redis.xtrim('s1', 0, limit: 1) }
138+
assert_equal "ERR syntax error, LIMIT cannot be used without the special ~ option", error.message
139+
ensure
140+
redis.config(:set, 'stream-node-max-entries', original)
141+
end
142+
end
143+
144+
def test_xtrim_with_maxlen_strategy
145+
redis.xadd('s1', { f: 'v1' }, id: '0-1')
146+
redis.xadd('s1', { f: 'v1' }, id: '0-2')
147+
redis.xadd('s1', { f: 'v1' }, id: '1-0')
148+
redis.xadd('s1', { f: 'v1' }, id: '1-1')
149+
assert_equal(2, redis.xtrim('s1', 2, strategy: 'MAXLEN'))
150+
end
151+
152+
def test_xtrim_with_minid_strategy
153+
omit_version('6.2.0')
154+
155+
redis.xadd('s1', { f: 'v1' }, id: '0-1')
156+
redis.xadd('s1', { f: 'v1' }, id: '0-2')
157+
redis.xadd('s1', { f: 'v1' }, id: '1-0')
158+
redis.xadd('s1', { f: 'v1' }, id: '1-1')
159+
assert_equal(2, redis.xtrim('s1', '1-0', strategy: 'MINID'))
160+
end
161+
162+
def test_xtrim_with_approximate_minid_strategy
163+
omit_version('6.2.0')
164+
165+
redis.xadd('s1', { f: 'v1' }, id: '0-1')
166+
redis.xadd('s1', { f: 'v1' }, id: '0-2')
167+
redis.xadd('s1', { f: 'v1' }, id: '1-0')
168+
redis.xadd('s1', { f: 'v1' }, id: '1-1')
169+
assert_equal(0, redis.xtrim('s1', '1-0', strategy: 'MINID', approximate: true))
170+
end
171+
172+
def test_xtrim_with_invalid_strategy
173+
omit_version('6.2.0')
174+
175+
redis.xadd('s1', { f: 'v1' })
176+
error = assert_raises(Redis::CommandError) { redis.xtrim('s1', '1-0', strategy: '') }
177+
assert_equal "ERR syntax error", error.message
178+
end
179+
124180
def test_xtrim_with_not_existed_stream
125181
assert_equal 0, redis.xtrim('not-existed-stream', 2)
126182
end
127183

128184
def test_xtrim_with_invalid_arguments
129185
if version >= '6.2'
130186
assert_raises(Redis::CommandError) { redis.xtrim('', '') }
131-
assert_raises(Redis::CommandError) { redis.xtrim(nil, nil) }
132187
assert_equal 0, redis.xtrim('s1', 0)
133188
assert_raises(Redis::CommandError) { redis.xtrim('s1', -1, approximate: true) }
134189
else
135190
assert_equal 0, redis.xtrim('', '')
136-
assert_equal 0, redis.xtrim(nil, nil)
137191
assert_equal 0, redis.xtrim('s1', 0)
138192
assert_equal 0, redis.xtrim('s1', -1, approximate: true)
139193
end

0 commit comments

Comments
 (0)