位图,这块怎么理解呢?其实我个人也没怎么用过,只是从公众号、博客上多多少少了解到一点信息。
我对位图的理解,可以从字面意思去理解,这里强调“位”,感觉就是用来存储0/1的数组。看看了官方介绍,位图其实就是普通的字符串,也就是byte数组。
位数数组是自动扩展的,如果设置了某个偏移位置超出了现有的内容范围,就会自动将位数组进行扩充并全部填充0
位图其实就是把字符转成byte格式,而1B=8b,正好是0/1方式,然后把1填充到数组中(该数组默认所有值都是0)。
常用指令:
①getbit/setbit
②bitcount:统计指定位置范围内1的个数
③bitpos:查找指定范围内出现的第一个0或1。
④注意事项:bitcount和bitpos都可以指定范围参数[start, end],start和end参数是字节索引,也就是说指定的位范围必须是8的倍数,即start和end指定的范围是:8 * 指定的数字。
⑤bitfield:由于getbit/setbit一次性只能操作一个位,因此为了方便一次性批量操作多个位,Redis3.2版本新增bitfield,其最多也就处理64个连续位,如果超过64位,就得使用多个子指令,bitfield可以一次执行多个子指令。
bitfield有三个子指令:get/set/incrby。
get指令,需要指明无符号数u还是有符号数i,所谓有符号数是指获取的位数组中第一个位是符号位,剩下的才是值。如果第一位是 1,那就是负数。无符号数表示非负数,没有符号位,获取的位数组全部都是值。有符号数最多可以获取 64 位,无符号数只能获取63位。如果超出位数限制,Redis抛出参数错误。
incrby指令,它用来对指定范围的位进行自增/自减。自增就有可能出现溢出,如果增加正数会出现上溢,如果增加负数就会出现下溢出。Redis默认的处理方式是:如果出现了溢出,就将溢出的符号位丢掉。如果是8位无符号数255加1后就会溢出则全部变零。如果是 8位有符号数127加1后就会溢出变成-128。
针对这种溢出情况,bitfield指令另外提供溢出策略子指令overflow,可以选择自己想要的溢出行为:默认是折返(wrap)、失败(fail) 报错不执行、饱和截断 (sat)超过了范围就停留在最大最小值。只不过overflow 指令只影响接下来的第一条指令,这条指令执行完后溢出策略会变成默认值折返 (wrap)。