Bitmap简介
1、Redis中的位图就是字符串,也就是byte数组,可以使用get/set直接获取和设置整个位图的内容,也可以使用位图操作getbit/setbit等将byte数组看成“位数组”来处理
2、Redis的位数组是自动扩展的,如果设置了某个偏移位置超出了现有的内容范围,就会自动将位数组进行零扩充
3、有符号数是指获取的位数组中第一个位是符号位,剩下的才是值。如果第一位是1,那就是负数。无符号数表示非负数,没有符号位,获取的位数组全部都是值。有符号数最多可以获取 64 位,无符号数只能获取63位 (因为 Redis协议中的integer是有符号数,最大64位,不能传递64位无符号值)
使用到的命令
下标都是从0开始的
setbit key index value #设置bitmap中某一位的值
getbit key index #获取bitmap中某一位的值
bitcount key startindex endindex #查找下标范围内字符中1的个数,startindex和endindex是以字节为单位的,所以位数是8的倍数
bitpos key bit startindex endindex #查找指定范围字符中的第一次出现bit的下标
位数组高低位
二进制中位数高地位的定义是
高 -> 低
Redis位数组的顺序是(下标还是从0开始的)
低 -> 高
所以设置Bitmap的时候需要做对应的转换
比如说要设置hello字符串
将每个字母都转换为二进制,Python中二进制以0b开头
那么hello的二进制为 01101000(h) 01100101(e) 01101100(l) 01101100(l) 01101111(o)
从左到右二进制拼起来就是 0110100001100101011011000110110001101111
Redis由低到高是 低->0110100001100101011011000110110001101111->高 从零开始数下标,设置的时候使用
setbit key index value #设置bitmap中某一位的值
零存就是使用 setbit 对位值进行逐个设置,整存就是使用字符串一次性填充所有位数组,覆盖掉旧值;setbit时如果对应位的字节是不可打印字符,那么get的时候会显示为16进制
整存整取
setbit设置某一位的值,getbit取某一位的值
setbit key index value #设置bitmap中某一位的值
getbit key index #获取bitmap中某一位的值
整存零取
set设置字符串的值,getbit获取某一位的值
set key value #设置字符串的值
getbit key index #获取bitmap中某一位的值
Redis bitfield指令
参考:https://www.w3cschool.cn/doc_redis/redis-bitfield.html
1、bitfield有三个子指令,分别是get/set/incrby,它们都可以对指定位片段进行读写,但是最多只能处理64个连续的位,如果超过64位,就得使用多个子指令,bitfield 可以一次执行多个子指令
2、Redis中Integer是有符号数最大64位,不能传递64位无符号值,所以无符号数只能获取63位
bitfield [key] get u[num] [startindex] #从key中的第startindex位开始取num位,结果是无符号数(注意这里拿的是反码)
bitfield [key] get i[num] [startindex] #从key中的第startindex位开始取num位,结果是有符号数(注意这里拿的是反码)
bitfield [key] set u[num] [starindex] [value] #从第starindex位开始,讲接下来的num位用无符号数value替换(value是ASCII值)
bitfield [key] set i[num] [starindex] [value] #从第starindex位开始,讲接下来的num位用有符号数value替换(value是ASCII值)
bitfield指令中的incrby
1、指令incrby,它用来对指定范围的位进行自增操作。既然提到自增,就有可能出现溢出。如果增加了正数,会出现上溢,如果增加的是负数,就会出现下溢出。Redis默认的处理是折返。如果出现了溢出,就将溢出的符号位丢掉。如果是8位无符号数255,加1后就会溢出,会全部变零。如果是8位有符号数127,加1后就会溢出变成-128
bitfield [key] incrby u[num] [startindex] [value] overflow [wrap/fail/sat] #从第startindex位开始,对接下来的num位无符号数加上value;对于数值溢出,使用的策略(默认是wrap)