Skip to main content

BITPOS

Introduction​

In Dragonfly, as well as in Redis and Valkey, the BITPOS command is used to find the first occurrence of a bit set to 1 or 0 in a binary string. This command is particularly useful for efficiently locating bit transitions and is commonly used in scenarios like sparse data structures, flags, or low-level data processing.

Syntax​

BITPOS key bit [start [end [BYTE|BIT]]]
  • Time complexity: O(N)
  • ACL categories: @read, @bitmap, @slow

Parameter Explanations​

  • key: The key of the string in which the search will occur.
  • bit: The bit value to search for, which can be either 0 or 1.
  • start (optional): The starting byte position from which to begin the search. Default is 0.
  • end (optional): The ending byte position. Default is -1, which represents the end of the string.
  • BYTE|BIT (optional): The unit to consider while searching. If not specified, BYTE is used.

Return Values​

The command returns the position (index) of the first occurrence of the specified bit (0 or 1). If the bit is not found within the range, -1 is returned.

Code Examples​

Find the First 1 Bit​

In this example, we will find the first occurrence of 1 in the string:

# String: example
# Hex: 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65
# Binary: 01100101 01111000 01100001 01101101 01110000 01101100 01100101
dragonfly$> SET mykey "example"
OK
dragonfly$> BITPOS mykey 1
(integer) 1

The first occurrence of a 1 happens at bit position 1. (Remember, positions are zero-based).

Find the First 0 Bit​

Similarly, we can find the first occurrence of a 0 bit in the string:

dragonfly$> SET mykey "example"
OK
dragonfly$> BITPOS mykey 0
(integer) 0

In this case, the first occurrence of a 0 bit appears at position 0.

Narrowing the Search with a Byte Range​

We can specify a search range within bytes to limit the search. The following example looks for the first occurrence of 1 within the second and fourth bytes of the string:

# String: example
# Hex: 0x65 0x78 0x61 0x6d 0x70 0x6c 0x65
# Binary: 01100101 01111000 01100001 01101101 01110000 01101100 01100101
dragonfly$> SET mykey "example"
OK
dragonfly$> BITPOS mykey 1 1 3
(integer) 9

Here, we're telling the command to look only between the second and fourth bytes, and it finds the first 1 bit at position 9 (relative to the start of the string).

Using BITPOS in a Packed Flag System​

You can also use BITPOS in a system where flags are represented by bits within a packed binary string.

# Example binary string: 0x00 0x04 0x80
# Binary: 00000000 00000100 10000000
dragonfly$> SET flags "\x00\x04\x80"
OK
dragonfly$> BITPOS flags 1
(integer) 13

In this example, the first bit set to 1 is found at position 13.

Best Practices​

  • Utilize start and end to limit your search to specific sections of the string, improving performance for larger strings.
  • Use BITPOS when you need quick, efficient bit-level data scans without fully iterating through the data.

Common Mistakes​

  • Forgetting that the result is a bit offset, not a byte offset, especially when interpreting the result.
  • Assuming BITPOS modifies the string; it only performs a read and search operation.
  • Specifying an invalid bit parameter (it must be either 0 or 1).

FAQs​

Can I use negative indexes for the start and end parameters?​

Yes, negative indexes are allowed, and they signify positions from the end of the string.

How does the BYTE vs BIT modifier work?​

By default, BITPOS searches in BYTE mode, where each byte is processed sequentially. However, specifying BIT tells the function to treat the string bit-by-bit in the search. This mode is more granular and may be useful in certain low-level applications.