Skip to content

Commit 9a6abb4

Browse files
committed
Support BIT/BYTE for bitcount and bitpos for redis 7+
1 parent eb72f82 commit 9a6abb4

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

lib/redis/commands/bitmaps.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@ def getbit(key, offset)
2727
# @param [String] key
2828
# @param [Integer] start start index
2929
# @param [Integer] stop stop index
30+
# @param [String, Symbol] scale the scale of the offset range
31+
# e.g. 'BYTE' - interpreted as a range of bytes, 'BIT' - interpreted as a range of bites
3032
# @return [Integer] the number of bits set to 1
31-
def bitcount(key, start = 0, stop = -1)
32-
send_command([:bitcount, key, start, stop])
33+
def bitcount(key, start = 0, stop = -1, scale: nil)
34+
command = [:bitcount, key, start, stop]
35+
command << scale.to_s.upcase if scale
36+
send_command(command)
3337
end
3438

3539
# Perform a bitwise operation between strings and store the resulting string in a key.
@@ -51,14 +55,17 @@ def bitop(operation, destkey, *keys)
5155
# @param [Integer] bit whether to look for the first 1 or 0 bit
5256
# @param [Integer] start start index
5357
# @param [Integer] stop stop index
58+
# @param [String, Symbol] scale the scale of the offset range
59+
# e.g. 'BYTE' - interpreted as a range of bytes, 'BIT' - interpreted as a range of bites
5460
# @return [Integer] the position of the first 1/0 bit.
5561
# -1 if looking for 1 and it is not found or start and stop are given.
56-
def bitpos(key, bit, start = nil, stop = nil)
62+
def bitpos(key, bit, start = nil, stop = nil, scale: nil)
5763
raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start
5864

5965
command = [:bitpos, key, bit]
6066
command << start if start
6167
command << stop if stop
68+
command << scale.to_s.upcase if scale
6269
send_command(command)
6370
end
6471
end

lib/redis/distributed.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ def append(key, value)
370370
end
371371

372372
# Count the number of set bits in a range of the string value stored at key.
373-
def bitcount(key, start = 0, stop = -1)
374-
node_for(key).bitcount(key, start, stop)
373+
def bitcount(key, start = 0, stop = -1, scale: nil)
374+
node_for(key).bitcount(key, start, stop, scale: scale)
375375
end
376376

377377
# Perform a bitwise operation between strings and store the resulting string in a key.
@@ -383,8 +383,8 @@ def bitop(operation, destkey, *keys)
383383
end
384384

385385
# Return the position of the first bit set to 1 or 0 in a string.
386-
def bitpos(key, bit, start = nil, stop = nil)
387-
node_for(key).bitpos(key, bit, start, stop)
386+
def bitpos(key, bit, start = nil, stop = nil, scale: nil)
387+
node_for(key).bitpos(key, bit, start, stop, scale: scale)
388388
end
389389

390390
# Set the string value of a key and return its old value.

test/lint/strings.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,15 @@ def test_bitcount
249249
assert_equal 17, r.bitcount("foo", 0, -1)
250250
end
251251

252+
def test_bitcount_bits_range
253+
target_version "7.0" do
254+
r.set("foo", "abcde")
255+
256+
assert_equal 10, r.bitcount("foo", 8, 31, scale: :bit)
257+
assert_equal 17, r.bitcount("foo", 0, -1, scale: :byte)
258+
end
259+
end
260+
252261
def test_getrange
253262
r.set("foo", "abcde")
254263

test/redis/bitpos_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ def test_bitpos_one_intervals
4141
assert_equal(8, r.bitpos("foo", 1, 1, 1))
4242
end
4343

44+
def test_bitpos_one_intervals_bit_range
45+
target_version "7.0" do
46+
r.set "foo", "\x00\xff\x00"
47+
assert_equal(8, r.bitpos("foo", 1, 8, -1, scale: 'bit'))
48+
assert_equal(-1, r.bitpos("foo", 1, 8, -1, scale: 'byte'))
49+
end
50+
end
51+
4452
def test_bitpos_raise_exception_if_stop_not_start
4553
assert_raises(ArgumentError) do
4654
r.bitpos("foo", 0, nil, 2)

0 commit comments

Comments
 (0)