Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Redis 6.2] Add ZDIFFSTORE command #1046

Merged
merged 1 commit into from
Oct 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 38 additions & 26 deletions lib/redis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2279,20 +2279,10 @@ def zinter(*args)
# sorted sets
# - `:aggregate => String`: aggregate function to use (sum, min, max)
# @return [Integer] number of elements in the resulting sorted set
def zinterstore(destination, keys, weights: nil, aggregate: nil)
args = [:zinterstore, destination, keys.size, *keys]

if weights
args << "WEIGHTS"
args.concat(weights)
end

args << "AGGREGATE" << aggregate if aggregate

synchronize do |client|
client.call(args)
end
def zinterstore(*args)
_zsets_operation_store(:zinterstore, *args)
end
ruby2_keywords(:zinterstore) if respond_to?(:ruby2_keywords, true)

# Return the union of multiple sorted sets
#
Expand Down Expand Up @@ -2331,20 +2321,10 @@ def zunion(*args)
# sorted sets
# - `:aggregate => String`: aggregate function to use (sum, min, max, ...)
# @return [Integer] number of elements in the resulting sorted set
def zunionstore(destination, keys, weights: nil, aggregate: nil)
args = [:zunionstore, destination, keys.size, *keys]

if weights
args << "WEIGHTS"
args.concat(weights)
end

args << "AGGREGATE" << aggregate if aggregate

synchronize do |client|
client.call(args)
end
def zunionstore(*args)
_zsets_operation_store(:zunionstore, *args)
end
ruby2_keywords(:zunionstore) if respond_to?(:ruby2_keywords, true)

# Return the difference between the first and all successive input sorted sets
#
Expand All @@ -2370,6 +2350,23 @@ def zdiff(*keys, with_scores: false)
_zsets_operation(:zdiff, *keys, with_scores: with_scores)
end

# Compute the difference between the first and all successive input sorted sets
# and store the resulting sorted set in a new key
#
# @example
# redis.zadd("zsetA", [[1.0, "v1"], [2.0, "v2"]])
# redis.zadd("zsetB", [[3.0, "v2"], [2.0, "v3"]])
# redis.zdiffstore("zsetA", "zsetB")
# # => 1
#
# @param [String] destination destination key
# @param [Array<String>] keys source keys
# @return [Integer] number of elements in the resulting sorted set
def zdiffstore(*args)
_zsets_operation_store(:zdiffstore, *args)
end
ruby2_keywords(:zdiffstore) if respond_to?(:ruby2_keywords, true)

# Get the number of fields in a hash.
#
# @param [String] key
Expand Down Expand Up @@ -3924,6 +3921,21 @@ def _zsets_operation(cmd, *keys, weights: nil, aggregate: nil, with_scores: fals
client.call(command, &block)
end
end

def _zsets_operation_store(cmd, destination, keys, weights: nil, aggregate: nil)
command = [cmd, destination, keys.size, *keys]

if weights
command << "WEIGHTS"
command.concat(weights)
end

command << "AGGREGATE" << aggregate if aggregate

synchronize do |client|
client.call(command)
end
end
end

require_relative "redis/version"
Expand Down
8 changes: 8 additions & 0 deletions lib/redis/distributed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,14 @@ def zdiff(*keys, **options)
end
end

# Compute the difference between the first and all successive input sorted sets
# and store the resulting sorted set in a new key.
def zdiffstore(destination, keys, **options)
ensure_same_node(:zdiffstore, [destination] + keys) do |node|
node.zdiffstore(destination, keys, **options)
end
end

# Get the number of fields in a hash.
def hlen(key)
node_for(key).hlen(key)
Expand Down
4 changes: 4 additions & 0 deletions test/cluster_commands_on_sorted_sets_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ def test_zunionstore_with_weights
def test_zdiff
assert_raises(Redis::CommandError) { super }
end

def test_zdiffstore
assert_raises(Redis::CommandError) { super }
end
end
4 changes: 4 additions & 0 deletions test/distributed_commands_on_sorted_sets_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,8 @@ def test_zunionstore_with_weights
def test_zdiff
assert_raises(Redis::Distributed::CannotDistribute) { super }
end

def test_zdiffstore
assert_raises(Redis::Distributed::CannotDistribute) { super }
end
end
16 changes: 16 additions & 0 deletions test/lint/sorted_sets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,22 @@ def test_zdiff
end
end

def test_zdiffstore
target_version("6.2") do
r.zadd 'foo', 1, 's1'
r.zadd 'foo', 2, 's2'
r.zadd 'bar', 3, 's1'
r.zadd 'bar', 5, 's3'

assert_equal 0, r.zdiffstore('baz', ['foo', 'foo'])
assert_equal 2, r.zdiffstore('baz', ['foo'])
assert_equal ['s1', 's2'], r.zrange('baz', 0, -1)

assert_equal 1, r.zdiffstore('baz', ['foo', 'bar'])
assert_equal ['s2'], r.zrange('baz', 0, -1)
end
end

def test_zinter
target_version("6.2") do
r.zadd 'foo', 1, 's1'
Expand Down