Redis BITFIELD命令—同时设置BitMap的多个位

BITFIELD命令可以在同一命令调用中操作多个位字段。它可支持多种操作,并返回一个对应每个操作答复数组。

该命令将Redis字符串视为bit位数组,并且能够处理可变位宽和任意偏移量的特定整数字段。 例如,您可以使用此命令将位偏移量1234处的有符号5位整数设置为特定值,从偏移量4567中检索31位无符号整数。类似地,该命令可处理指定整数的增减。

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

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

可用版本:从3.2.0开始可用 时间复杂度:O(1)

命令格式

BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]

返回值

本命令返回一个对应每一个子命令的按子命令顺序的子命令结果的数组。除了OVERFLOW子命令不生成答复。

命令详解

注意:

  1. GET命令指定一个超过字符串长度的偏移量(包括键根本不存在的情况),命令将按不存在的部分都由设置为0的位组成来执行。
  2. SETINCRBY命令指定一个超过字符串长度的偏移量将扩展字符串,并根据需要使用零填充扩展部分。

支持的子命令及整数类型

以下是支持的命令列表:

  • GET <type> <offset> --返回指定的bit位字段。
  • SET <type> <offset> --设置指定的bit位字段的值并返回它的旧值。
  • INCRBY <type> <offset> --对指定的bit位字段处的值执行加或减(如果指定负数增量)操作。

还有另一个子命令,只改变INCRBY子命令的溢出行为:

  • OVERFLOW [WRAP|SAT|FAIL]

支持的数据类型:

  • 无符号整数,u+整数占用的位数,例如:u8表示8位无符号整数。最多支持63位无符号整数,不支持64位无符号整数,因为Redis协议不运行64位无符号整数作为答复。
  • 有符号整数,i+整数占用的位数,例如:i16表示16位有符号整数。最多支持64位有符号整数。

两种偏移量(offset)的表示方式

BITFIELD命令有两种指定偏移量的方式,单独的数字,没有指定前辍表不以bit位为单位的偏移量。

然而,如果offset前面加了一个#字符,偏移量要乘于整数类型的宽度,如下例子所示:

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

设置位于偏移量0处的第一个i8类型整数和位于偏移量1处的第二个i8类型整数。使用这种方式您不需要自己计算位偏移量。

溢出控制

使用OVERFLOW命令,通过将OVERFLOW设置为下列值,您可以调整加减运算时溢出行为:

  • WRAP:环绕,不管有符号和无符号整型。对于无符号整型,环绕行为就相当于执行了对整型能表示的最大整数的取模操作。对于有符号整型,环绕行为表示向上溢出将回到最小负数,向下溢出将回到最大正数。例如,如果一个i8整数类型被设置为127,再对它进行加1操作,结果将为-128。

  • SAT:使用饱和算法,即在下溢时将值设置为最小整数值,在上溢时将值设置为最大整数值。 例如,对值为120的i8整数加10,将得到127,并且进一步的执行加操作也将始终保持为127。下溢时也会发生这种情况,到达该值的最大负值时值将不再减小。

  • FAIL:在此模式下,检测到的上溢或下溢时将不执行任何操作。 相应的返回值设置为NULL,以将发生的情况告知调用方。

注意,OVERFLOW语句只影响在它之后的INCRBY命令,直到出到下一个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

动机

此命令的动机是将许多小整数存储为单个大位图(或分割成几个键以避免大键),这样的存储效率极高。

性能考量

通常BITFIELD命令执行很快。需要注意的是,对一个很短的字符串访问其很大长度的数据将触发内存分配,这可能比访问已存在的数据要更加耗时。