Skip to content

Commit

Permalink
Merge pull request #1195 from JerrodCarpenter/lmpop
Browse files Browse the repository at this point in the history
✨ Add LMPOP
  • Loading branch information
byroot committed May 30, 2023
2 parents 1f4041a + c787721 commit fde7873
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
26 changes: 26 additions & 0 deletions lib/redis/commands/lists.rb
Expand Up @@ -183,6 +183,32 @@ def brpoplpush(source, destination, timeout: 0)
send_blocking_command(command, timeout)
end

# Pops one or more elements from the first non-empty list key from the list
# of provided key names.
#
# @example Popping a element
# redis.lmpop('list')
# #=> ['list', ['a']]
# @example With count option
# redis.lmpop('list', count: 2)
# #=> ['list', ['a', 'b']]
#
# @params key [String, Array<String>] one or more keys with lists
# @params modifier [String]
# - when `"LEFT"` - the elements popped are those from the left of the list
# - when `"RIGHT"` - the elements popped are those from the right of the list
# @params count [Integer] a number of elements to pop
#
# @return [Array<String, Array<String, Float>>] list of popped elements or nil
def lmpop(*keys, modifier: "LEFT", count: nil)
raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT"

args = [:lmpop, keys.size, *keys, modifier]
args << "COUNT" << Integer(count) if count

send_command(args)
end

# Get an element from a list by its index.
#
# @param [String] key
Expand Down
7 changes: 7 additions & 0 deletions lib/redis/distributed.rb
Expand Up @@ -542,6 +542,13 @@ def ltrim(key, start, stop)
node_for(key).ltrim(key, start, stop)
end

# Iterate over keys, removing elements from the first non list set found.
def lmpop(*keys, modifier: "LEFT", count: nil)
ensure_same_node(:lmpop, keys) do |node|
node.lmpop(*keys, modifier: modifier, count: count)
end
end

# Get the number of members in a set.
def scard(key)
node_for(key).scard(key)
Expand Down
13 changes: 13 additions & 0 deletions test/lint/lists.rb
Expand Up @@ -202,5 +202,18 @@ def test_variadic_rpoplpush_expand
redis.rpush('{1}bar', %w[d e f])
assert_equal 'c', redis.rpoplpush('{1}foo', '{1}bar')
end

def test_lmpop
target_version('7.0') do
assert_nil r.lmpop('{1}foo')

r.lpush('{1}foo', %w[a b c d e f g])
assert_equal ['{1}foo', ['g']], r.lmpop('{1}foo')
assert_equal ['{1}foo', ['f', 'e']], r.lmpop('{1}foo', count: 2)

r.lpush('{1}foo2', %w[a b])
assert_equal ['{1}foo', ['a']], r.lmpop('{1}foo', '{1}foo2', modifier: "RIGHT")
end
end
end
end

0 comments on commit fde7873

Please sign in to comment.