BITPOS(3valkey)

πŸ“¦
version 9.0.6 Β· 2 versions
, in fedora 44

πŸ’… BITPOS β€” the vibe check for your bits

okay bestie, so this is bitpos from the Valkey Command Manual (manual name: BITPOS(3valkey), in case you were wondering what you opened) and it's literally the "where's the first one tho" command. let's go πŸŽ€


✨ NAME ✨

bitpos β€” finds the first set (1) or clear (0) bit in a string. that's it, that's the job. πŸ¦‹


✨ SYNOPSIS ✨

BITPOS key bit [start [end [BYTE | BIT]]]

✨ DESCRIPTION ✨

so basically: it returns the position of the first bit set to 1 or 0 in a string. like, where does the first one (or first zero) live. 🫢

and the way we count? think of the string as an array of bits going left to right, where the first byte's most significant bit sits at position 0, the second byte's most significant bit sits at position 8, and so on forever. same convention as valkey-getbit(7) GETBIT and valkey-setbit(7) SETBIT, so if you know those, you already know the vibe. no cap.

by default, every single byte in the string gets examined. but you can be picky and only look in a specific interval by passing the extra start and end arguments. you can also just pass start and the operation will assume end is the last byte of the string. ⚠️ BUT β€” and this is the plot twist β€” there are semantic differences, and we'll get to those. by default the range is interpreted as a range of bytes, not bits, so start=0 and end=2 means "look at the first three bytes". πŸ“

you can also drop the optional BIT modifier to say "actually, interpret this range as a range of bits". so then start=0 and end=2 means "look at the first three bits". cute, right?

heads up bestie: bit positions are always returned as absolute values starting from bit zero, even when you're using start and end to specify a range. the range narrows the search, it does not renumber the results. πŸ’€

similar to the valkey-getrange(7) GETRANGE command, start and end can be negative so you can index from the end of the string β€” -1 is the last byte, -2 is the penultimate, and so forth. and when BIT is specified? -1 is the last bit, -2 is the penultimate, and so forth. same energy, different unit. πŸ’…

and non-existent keys? treated as empty strings. they're just out here living their empty little lives. πŸ™ˆ


✨ REPLY ✨

one of these, bestie:

  • valkey-protocol(7) Integer reply: the position of the first bit set to 1 or 0 according to the request πŸŽ€
  • valkey-protocol(7) Integer reply: -1. this happens when the bit argument is 1 and the string is empty or composed of just zero bytes.

let me spell it out because this part is giving nuance:

if we're looking for set bits (the bit argument is 1) and the string is empty or made of nothing but zero bytes, you get -1 back. that's the "nope, nothing here" answer. 😭

if we're looking for clear bits (the bit argument is 0) and the string only contains bits set to 1, the function returns the first bit not part of the string on the right. so if the string is three bytes all set to the value 0xff, then BITPOS key 0 returns 24, since up to bit 23 every bit is a 1. math is math. πŸ”₯

the function considers the right of the string as padded with zeros if you're looking for clear bits and you specify no range, or only the start argument.

⚠️ however β€” this behavior changes if you're looking for clear bits and you specify a range with both start and end. different rules, different results, stay woke.

and if a clear bit isn't found in the specified range, the function returns -1, because the user specified a clear range and there are literally no 0 bits in it. periodt. πŸ‘‘


✨ COMPLEXITY ✨

O(N) β€” linear, babe. it's gonna walk the string. ⭐


✨ ACL CATEGORIES ✨

@bitmap @read @slow


✨ HISTORY ✨

  • available since: 2.8.7 🌸
  • changed in 7.0.0: added the BYTE|BIT option. ✨

✨ EXAMPLES ✨

watch and learn, bestie πŸ’–

127.0.0.1:6379> SET mykey "\xff\xf0\x00"
OK
127.0.0.1:6379> BITPOS mykey 0
(integer) 12
127.0.0.1:6379> SET mykey "\x00\xff\xf0"
OK
127.0.0.1:6379> BITPOS mykey 1 0
(integer) 8
127.0.0.1:6379> BITPOS mykey 1 2
(integer) 16
127.0.0.1:6379> BITPOS mykey 1 2 -1 BYTE
(integer) 16
127.0.0.1:6379> BITPOS mykey 1 7 15 BIT
(integer) 8
127.0.0.1:6379> set mykey "\x00\x00\x00"
OK
127.0.0.1:6379> BITPOS mykey 1
(integer) -1
127.0.0.1:6379> BITPOS mykey 1 7 -3 BIT
(integer) -1

✨ SEE ALSO ✨

bitcount(3valkey), bitfield(3valkey), bitfield_ro(3valkey), bitop(3valkey), getbit(3valkey), setbit(3valkey) β€” go read the whole bit family, they're all icons πŸ‘‘


and that's the tea, bestie 🫢 this was version 9.0.0 of the Valkey Command Manual, dated 2025-10-21. mwah, go find some bits. πŸ’œβœ¨

πŸ“¦ where this page comes from