Skip to content

Commit 5eb0c14

Browse files
committed
Merge pull request #432 from maxd/master
Add HyperLogLog commands (#431)
2 parents 522e7a5 + 4219f40 commit 5eb0c14

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

lib/redis.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,6 +2436,39 @@ def sscan_each(key, options={}, &block)
24362436
end
24372437
end
24382438

2439+
# Add one or more members to a HyperLogLog structure.
2440+
#
2441+
# @param [String] key
2442+
# @param [String, Array<String>] member one member, or array of members
2443+
# @return [Boolean] true if at least 1 HyperLogLog internal register was altered. false otherwise.
2444+
def pfadd(key, member)
2445+
synchronize do |client|
2446+
client.call([:pfadd, key, member], &_boolify)
2447+
end
2448+
end
2449+
2450+
# Get the approximate cardinality of members added to HyperLogLog structure.
2451+
#
2452+
# @param [String] key
2453+
# @return [Fixnum]
2454+
def pfcount(key)
2455+
synchronize do |client|
2456+
client.call([:pfcount, key])
2457+
end
2458+
end
2459+
2460+
# Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of
2461+
# the observed Sets of the source HyperLogLog structures.
2462+
#
2463+
# @param [String] dest_key destination key
2464+
# @param [String, Array<String>] source_key source key, or array of keys
2465+
# @return [Boolean]
2466+
def pfmerge(dest_key, *source_key)
2467+
synchronize do |client|
2468+
client.call([:pfmerge, dest_key, *source_key], &_boolify_set)
2469+
end
2470+
end
2471+
24392472
def id
24402473
@original_client.id
24412474
end

lib/redis/distributed.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,24 @@ def script(subcommand, *args)
786786
on_each_node(:script, subcommand, *args)
787787
end
788788

789+
# Add one or more members to a HyperLogLog structure.
790+
def pfadd(key, member)
791+
node_for(key).pfadd(key, member)
792+
end
793+
794+
# Get the approximate cardinality of members added to HyperLogLog structure.
795+
def pfcount(key)
796+
node_for(key).pfcount(key)
797+
end
798+
799+
# Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of
800+
# the observed Sets of the source HyperLogLog structures.
801+
def pfmerge(dest_key, *source_key)
802+
ensure_same_node(:pfmerge, [dest_key, *source_key]) do |node|
803+
node.pfmerge(dest_key, *source_key)
804+
end
805+
end
806+
789807
def _eval(cmd, args)
790808
script = args.shift
791809
options = args.pop if args.last.is_a?(Hash)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# encoding: UTF-8
2+
3+
require File.expand_path("helper", File.dirname(__FILE__))
4+
require "lint/hyper_log_log"
5+
6+
class TestCommandsOnHyperLogLog < Test::Unit::TestCase
7+
8+
include Helper::Client
9+
include Lint::HyperLogLog
10+
11+
def test_pfmerge
12+
target_version "2.8.9" do
13+
r.pfadd "foo", "s1"
14+
r.pfadd "bar", "s2"
15+
16+
assert_equal true, r.pfmerge("res", "foo", "bar")
17+
assert_equal 2, r.pfcount("res")
18+
end
19+
end
20+
21+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# encoding: UTF-8
2+
3+
require File.expand_path("helper", File.dirname(__FILE__))
4+
require "lint/hyper_log_log"
5+
6+
class TestDistributedCommandsOnHyperLogLog < Test::Unit::TestCase
7+
8+
include Helper::Distributed
9+
include Lint::HyperLogLog
10+
11+
def test_pfmerge
12+
target_version "2.8.9" do
13+
assert_raise Redis::Distributed::CannotDistribute do
14+
r.pfadd "foo", "s1"
15+
r.pfadd "bar", "s2"
16+
17+
assert r.pfmerge("res", "foo", "bar")
18+
end
19+
end
20+
end
21+
22+
end

test/lint/hyper_log_log.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Lint
2+
3+
module HyperLogLog
4+
5+
def test_pfadd
6+
target_version "2.8.9" do
7+
assert_equal true, r.pfadd("foo", "s1")
8+
assert_equal true, r.pfadd("foo", "s2")
9+
assert_equal false, r.pfadd("foo", "s1")
10+
11+
assert_equal 2, r.pfcount("foo")
12+
end
13+
end
14+
15+
def test_variadic_pfadd
16+
target_version "2.8.9" do
17+
assert_equal true, r.pfadd("foo", ["s1", "s2"])
18+
assert_equal true, r.pfadd("foo", ["s1", "s2", "s3"])
19+
20+
assert_equal 3, r.pfcount("foo")
21+
end
22+
end
23+
24+
def test_pfcount
25+
target_version "2.8.9" do
26+
assert_equal 0, r.pfcount("foo")
27+
28+
assert_equal true, r.pfadd("foo", "s1")
29+
30+
assert_equal 1, r.pfcount("foo")
31+
end
32+
end
33+
34+
def test_variadic_pfcount
35+
target_version "2.8.9" do
36+
assert_equal 0, r.pfcount(["foo", "bar"])
37+
38+
assert_equal true, r.pfadd("foo", "s1")
39+
assert_equal true, r.pfadd("bar", "s1")
40+
assert_equal true, r.pfadd("bar", "s2")
41+
42+
assert_equal 2, r.pfcount(["foo", "bar"])
43+
end
44+
end
45+
46+
end
47+
48+
end

0 commit comments

Comments
 (0)