比特菲尔德

语法
BITFIELD key [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL>]
  <SET encoding offset value | INCRBY encoding offset increment>
  [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL>]
  <SET encoding offset value | INCRBY encoding offset increment>
  ...]]
从以下位置开始可用:
3.2.0
时间复杂度:
O(1) 对于每个指定的子命令
ACL 类别:
@write, @bitmap, @slow,

该命令将 Redis 字符串视为位数组,并且能够寻址具有不同位宽和任意(必要)对齐偏移量的特定整数字段。实际上,使用此命令,例如,可以将位偏移量为 1234 的有符号 5 位整数设置为特定值,从偏移量 4567 中检索 31 位无符号整数。同样,该命令处理指定整数的递增和递减,从而提供用户可以配置的有保证且指定明确的溢出和下溢行为。

BITFIELD能够在同一命令调用中使用多个位字段进行作。它需要一个要执行的作列表,并返回一个回复数组,其中每个数组都与参数列表中的相应作匹配。

例如,以下命令在位偏移量 100 处递增 5 位有符号整数,并在位偏移量 0 处获取 4 位无符号整数的值:

> BITFIELD mykey INCRBY i5 100 1 GET u4 0
1) (integer) 1
2) (integer) 0

请注意:

  1. 寻址GET超出当前字符串长度的 bits (包括 key 根本不存在的情况),导致要执行的作,如 missing part all 由设置为 0 的 bits 组成。
  2. 寻址SETINCRBY当前字符串长度之外的位将放大字符串,并根据触及的最远位,根据需要为所需的最小长度进行零填充。

支持的子命令和整数编码

以下是支持的命令列表。

  • 获取 <encoding> <offset>-- 返回指定的位字段。
  • 设置 <encoding> <offset> <value>-- 设置指定的位字段并返回其旧值。
  • INCRBY <encoding> <offset> <increment>-- 递增或递减(如果给出负增量)指定的位字段并返回新值。

还有另一个子命令,它只改变 successive 的行为INCRBYSETsubcommands调用:

  • 溢出 [WRAP|SAT|FAIL]

在需要整数编码的情况下,可以通过在i对于有符号整数和u对于无符号整数,替换为我们的整数编码的位数。例如,u8是 8 位的无符号整数,i16是一个 16 位的有符号整数。

支持的编码包括:有符号整数最高 64 位,有符号整数最高 63 位 unsigned 整数。无符号整数的这种限制是由于 当前 Redis 协议无法返回 64 位无符号整数 作为回复。

位和位置偏移量

有两种方法可以在 bitfield 命令中指定偏移量。 如果指定了不带任何前缀的数字,则将其用作从 0 开始的数字 字符串内的 bit offset 值。

但是,如果偏移量以字符为前缀,则指定的偏移量 乘以整数编码的 width,例如:#

BITFIELD mystring SET i8 #0 100 SET i8 #1 200

将第一个 i8 整数设置在偏移量 0 处,第二个整数设置在偏移量 8 处。 这样,你就不必在客户端内部自己做数学运算,如果 你想要的是一个给定大小的整数的普通数组。

溢出控制

使用OVERFLOW命令,则用户能够微调 增量或减量溢出(或下溢),通过指定以下值之一 以下行为:

  • WRAP:环绕,包含有符号和无符号整数。对于无符号整数,换行就像对整数可以包含的最大值执行取模运算(C 标准行为)。使用有符号整数时,换行意味着溢出会向最负的值重新开始,并向最正的值下溢,因此,如果i8integer 设置为值 127,将其增加 1 将产生-128.
  • SAT:使用饱和算法,即在下溢时,该值设置为最小整数值,在溢出时设置为最大整数值。例如,递增i8从值 120 开始且增量为 10 的整数将得到值 127,进一步的增量将始终保持值 127。下溢也会发生同样的情况,但 towards 该值在最负的值处被阻止。
  • FAIL:在此模式下,不对检测到的溢出或下溢执行任何作。相应的返回值设置为 NULL 以向调用方发出条件信号。

请注意,每个OVERFLOW语句仅影响INCRBYSET在子命令列表中紧随其后的命令,直到下一个OVERFLOW陈述。

默认情况下,如果未另行指定,则使用 WRAP

> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 1
2) (integer) 1
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 2
2) (integer) 2
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 3
2) (integer) 3
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1
1) (integer) 0
2) (integer) 3

以下是OVERFLOW FAIL返回 NULL。

> BITFIELD mykey OVERFLOW FAIL incrby u2 102 1
1) (nil)

动机

此命令的动机是能够存储许多小整数 因为单个大位图(或分割几个键以避免拥有巨大的键)具有极高的内存效率,并为 Redis 的应用开辟了新的用例,尤其是在实时分析领域。以受控方式指定溢出的能力支持此用例。

有趣的事实:Reddit 的 2017 年愚人节项目 r/place 是使用 Redis BITFIELD 命令构建的,以便采用协作画布的内存中表示。

性能注意事项

通常BITFIELD是一个快速命令,但请注意,对当前短字符串的远位进行寻址将触发分配,这可能比对已存在的位执行命令的成本更高。

位顺序

使用的表示形式BITFIELD将位图视为具有 位号 0 是第一个字节的最高有效位,依此类推,因此 例如,将 5 位无符号整数设置为偏移量 7 处的值 23 到 Bitmap 之前设置为全零,将产生以下表示形式:

+--------+--------+
|00000001|01110000|
+--------+--------+

当偏移量和整数大小与 bytes 边界对齐时,这是 与 big endian 相同,但是当这种对齐不存在时,它很重要 )来了解字节内的位是如何排序的。

RESP2 回复

以下选项之一:

  • Array reply:每个条目都是在相同位置给出的子命令的相应结果。
  • Nil 回复:如果给出了 OVERFLOW FAIL 并且检测到溢出或下溢。

RESP3 回复

以下选项之一:

  • Array reply:每个条目都是在相同位置给出的子命令的相应结果。
  • 空回复:如果给出了 OVERFLOW FAIL 并且检测到溢出或下溢。

为本页评分
返回顶部 ↑