BITFIELD

语法
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>
  ...]]
可用版本
Redis 开源 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 寻址超出当前字符串长度的位(包括键根本不存在的情况),将导致操作表现得像缺失的部分全部由位设置为 0 组成。
  2. 使用 SETINCRBY 寻址超出当前字符串长度的位将扩大字符串,并根据触及的最远位,按需用零填充至所需的最小长度。

支持的子命令和整数编码

以下是支持的命令列表。

  • GET <encoding> <offset> -- 返回指定的位域。
  • SET <encoding> <offset> <value> -- 设置指定的位域并返回其旧值。
  • INCRBY <encoding> <offset> <increment> -- 增加或减少(如果给定负数增量)指定的位域并返回新值。

还有一个子命令,它通过设置溢出行为来改变后续 INCRBYSET 子命令调用的行为。

  • OVERFLOW [WRAP|SAT|FAIL]

在需要整数编码的地方,可以通过前缀 i 表示带符号整数,前缀 u 表示无符号整数,后面跟上整数编码的位数。例如,u8 是一个 8 位无符号整数,i16 是一个 16 位带符号整数。

支持的编码对于带符号整数最高为 64 位,对于无符号整数最高为 63 位。无符号整数的这个限制是由于目前 Redis 协议无法以回复形式返回 64 位无符号整数。

位和位置偏移量

在 bitfield 命令中,有两种指定偏移量的方式。如果指定一个不带任何前缀的数字,它将直接用作字符串内部的零基位偏移量。

然而,如果偏移量带有 # 字符前缀,则指定的偏移量将乘以整数编码的宽度。例如:

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

将在偏移量 0 处设置第一个 i8 整数,在偏移量 8 处设置第二个。这样,如果想要一个给定大小的整数数组,您无需在客户端中自行计算。

溢出控制

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

  • WRAP:环绕,适用于带符号和无符号整数。对于无符号整数,环绕就像对整数能包含的最大值取模(C 标准行为)。对于带符号整数,环绕意味着溢出时回到最负值,下溢时回到最正值。例如,如果一个 i8 整数被设置为值 127,将其增加 1 将得到 -128
  • SAT:使用饱和算术,即当下溢时值设置为最小整数值,当溢出时值设置为最大整数值。例如,将从值 120 开始的 i8 整数增加 10,结果将是值 127,并且后续的增加将始终使值保持在 127。下溢时也会发生同样的情况,但值会阻止在最负值。
  • 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 位无符号整数设置为值 23,位于偏移量 7 处,将产生以下表示形式:

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

当偏移量和整数大小与字节边界对齐时,这与大端字节序相同,但当这种对齐不存在时,理解字节内部位的顺序也很重要。

RESP2 回复

以下之一

RESP3 回复

以下之一


给本页评分
回到顶部 ↑