Skip to content

Commit 9c45c6c

Browse files
committed
Merge pull request #412 from badboy/bitpos
Implement bitpos command.
2 parents 813a424 + 628011c commit 9c45c6c

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

lib/redis.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,27 @@ def bitop(operation, destkey, *keys)
906906
end
907907
end
908908

909+
# Return the position of the first bit set to 1 or 0 in a string.
910+
#
911+
# @param [String] key
912+
# @param [Fixnum] bit whether to look for the first 1 or 0 bit
913+
# @param [Fixnum] start start index
914+
# @param [Fixnum] stop stop index
915+
# @return [Fixnum] the position of the first 1/0 bit.
916+
# -1 if looking for 1 and it is not found or start and stop are given.
917+
def bitpos(key, bit, start=nil, stop=nil)
918+
if stop and not start
919+
raise(ArgumentError, 'stop parameter specified without start parameter')
920+
end
921+
922+
synchronize do |client|
923+
command = [:bitpos, key, bit]
924+
command << start if start
925+
command << stop if stop
926+
client.call(command)
927+
end
928+
end
929+
909930
# Set the string value of a key and return its old value.
910931
#
911932
# @param [String] key

lib/redis/distributed.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ def bitop(operation, destkey, *keys)
323323
end
324324
end
325325

326+
# Return the position of the first bit set to 1 or 0 in a string.
327+
def bitpos(key, bit, start=nil, stop=nil)
328+
node_for(key).bitpos(key, bit, start, stop)
329+
end
330+
326331
# Set the string value of a key and return its old value.
327332
def getset(key, value)
328333
node_for(key).getset(key, value)

test/bitpos_test.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# encoding: UTF-8
2+
3+
require File.expand_path("helper", File.dirname(__FILE__))
4+
5+
unless defined?(Enumerator)
6+
Enumerator = Enumerable::Enumerator
7+
end
8+
9+
class TestBitpos < Test::Unit::TestCase
10+
11+
include Helper::Client
12+
13+
def test_bitpos_empty_zero
14+
target_version "2.9.11" do
15+
r.del "foo"
16+
assert_equal 0, r.bitpos("foo", 0)
17+
end
18+
end
19+
20+
def test_bitpos_empty_one
21+
target_version "2.9.11" do
22+
r.del "foo"
23+
assert_equal -1, r.bitpos("foo", 1)
24+
end
25+
end
26+
27+
def test_bitpos_zero
28+
target_version "2.9.11" do
29+
r.set "foo", "\xff\xf0\x00"
30+
assert_equal 12, r.bitpos("foo", 0)
31+
end
32+
end
33+
34+
def test_bitpos_one
35+
target_version "2.9.11" do
36+
r.set "foo", "\x00\x0f\x00"
37+
assert_equal 12, r.bitpos("foo", 1)
38+
end
39+
end
40+
41+
def test_bitpos_zero_end_is_given
42+
target_version "2.9.11" do
43+
r.set "foo", "\xff\xff\xff"
44+
assert_equal 24, r.bitpos("foo", 0)
45+
assert_equal 24, r.bitpos("foo", 0, 0)
46+
assert_equal -1, r.bitpos("foo", 0, 0, -1)
47+
end
48+
end
49+
50+
def test_bitpos_one_intervals
51+
target_version "2.9.11" do
52+
r.set "foo", "\x00\xff\x00"
53+
assert_equal 8, r.bitpos("foo", 1, 0, -1)
54+
assert_equal 8, r.bitpos("foo", 1, 1, -1)
55+
assert_equal -1, r.bitpos("foo", 1, 2, -1)
56+
assert_equal -1, r.bitpos("foo", 1, 2, 200)
57+
assert_equal 8, r.bitpos("foo", 1, 1, 1)
58+
end
59+
end
60+
61+
def test_bitpos_raise_exception_if_stop_not_start
62+
target_version "2.9.11" do
63+
assert_raises(ArgumentError) do
64+
r.bitpos("foo", 0, nil, 2)
65+
end
66+
end
67+
end
68+
69+
end

0 commit comments

Comments
 (0)