009-redis应用-02-位图getbit/setbit

一、概述

  位图不是特殊的数据结构,它的内容其实就是普通的字符串,也就是 byte 数组。

  可以使用普通的 get/set 直接获取和设置整个位图的内容,也可以使用位图操作 getbit/setbit 等将 byte 数组看成「位数组」来处理。

1.1、基础使用

  Redis 的位数组是自动扩展,如果设置了某个偏移位置超出了现有的内容范围,就会自 动将位数组进行零扩充。

  接下来我们使用位操作将字符串设置为 hello (不是直接使用 set 指令),首先我们需要得到 hello 的 ASCII 码

  

  接下来使用 redis-cli 设置第一个字符,也就是位数组的前 8 位,我们只需要设置值为 1 的位,如上图所示,h 字符只有 1/2/4 位需要设置,e 字符只有 9/10/13/15 位需要设置。值得注意的是位数组的顺序和字符的位顺序是相反的。

127.0.0.1:6379> setbit s 1 1 
(integer) 0
127.0.0.1:6379> setbit s 2 1 
(integer) 0
127.0.0.1:6379> setbit s 4 1 
(integer) 0
127.0.0.1:6379> setbit s 9 1 
(integer) 0
127.0.0.1:6379> setbit s 10 1 
(integer) 0
127.0.0.1:6379> setbit s 13 1 
(integer) 0
127.0.0.1:6379> setbit s 15 1 
(integer) 0
127.0.0.1:6379> get s
"he"

  设置:setbit key 数组下标 0/1,或者使用字符串方式设置:set key hello 

  读取:getbit key 数组下标,或者使用字符串方式设置:get key

1.2、统计和查找

  Redis 提供了位图统计指令 bitcount 和位图查找指令 bitpos,bitcount 用来统计指定位 置范围内 1 的个数,bitpos 用来查找指定范围内出现的第一个 0 或 1。 

  范围参数[start, end] ,start 和 end 参数是字节索引,也就是说指定的位范围必须是 8 的倍数, 而不能任意指定。 

  bitcount 用来统计指定位 置范围内 1 的个数,bitpos 用来查找指定范围内出现的第一个 0 或 1。 

示例 bitcount 指令和 bitpos 指令 :

127.0.0.1:6379> set w hello 
OK
127.0.0.1:6379> bitcount w 
(integer) 21
127.0.0.1:6379> bitcount w 0 0 # 第一个字符中 1 的位数
(integer) 3
127.0.0.1:6379> bitcount w 0 1 # 前两个字符中 1 的位数
(integer) 7
127.0.0.1:6379> bitpos w 0 # 第一个 0 位
 (integer) 0
127.0.0.1:6379> bitpos w 1 # 第一个 1 位
(integer) 1
127.0.0.1:6379> bitpos w 1 1 1 # 从第二个字符算起,第一个 1 位
(integer) 9
127.0.0.1:6379> bitpos w 1 2 2  从第三个字符算起,第一个 1 位
 (integer) 17

1.3、bitfield 一次进行多个位的操作 

  Redis 的 3.2 版本以后新增了一个指令,有 了这条指令,不用管道也可以一次进行多个位的操作。 bitfield 有三个子指令,分别是 get/set/incrby,它们都可以对指定位片段进行读写,但是最多只能处理 64 个连续的位,如果 超过 64 位,就得使用多个子指令,bitfield 可以一次执行多个子指令。

127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w get u4 0 # 从第一个位开始取 4 个位,结果是无符号数 (u)
(integer) 6
127.0.0.1:6379> bitfield w get u3 2 # 从第三个位开始取 3 个位,结果是无符号数 (u)
(integer) 5
127.0.0.1:6379> bitfield w get i4 0 # 从第一个位开始取 4 个位,结果是有符号数 (i) 
1) (integer) 6
127.0.0.1:6379> bitfield w get i3 2  # 从第三个位开始取 3 个位,结果是有符号数 (i)
1) (integer) -3

  所谓有符号数是指获取的位数组中第一个位是符号位,剩下的才是值。如果第一位是 1,那就是负数。无符号数表示非负数,没有符号位,获取的位数组全部都是值。有符号数最 多可以获取 64 位,无符号数只能获取 63 位 (因为 Redis 协议中的 integer 是有符号数, 最大 64 位,不能传递 64 位无符号值)。如果超出位数限制,Redis 就会告诉你参数错误。 

 

 

  

    

 

 

 

 

地方

 
posted @ 2020-03-30 15:03  bjlhx15  阅读(266)  评论(0编辑  收藏  举报
Copyright ©2011~2020 JD-李宏旭