美文网首页
位图的增强,bitfields

位图的增强,bitfields

作者: guessguess | 来源:发表于2020-10-25 12:31 被阅读0次

之前有一篇文章讲了位图的使用,然后简单做了个测试,模拟了签到的场景。
但是还是存在着一些问题,如果一个人一年一条签到记录,那么问题来了,怎么快速知道某个人在某个时间段内的签到次数呢?或者是想要批量修改某个时间段的签到呢?
bitCount指令只支持到以字节为单位,明显是不能支持以位为单位来查询的操作。
修改签到功能的话,那么setBit指令是支持的,但是批量修改总不能频繁去请求redis吧?

以上俩个问题都可以通过BitFields指令来解决。
那么下面来使用一下BitFields

环境需要

redis 3.2之后的版本

高->低位
h - > 1101000
e - > 1100101
l - > 1101100
l - > 1101100
o - > 1101111

根据位的范围进行查询

127.0.0.1:6379> set test hello
OK
127.0.0.1:6379> BITFIELD test get u8 0
1) (integer) 104
127.0.0.1:6379> BITFIELD test get u64 0
(error) ERR Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is.
127.0.0.1:6379> BITFIELD test get u63 0
1) (integer) 3761268982783410176

上面2个指令
第一个指令是直接设置一个key=test value=hello的一个键值对
第二个指令的话就是从0开始截取8位,返回来的值是无符的,刚刚好是h的字符的值,01101000转成十进制就是104,u就是无符,i就是有符,有符最多支持64位,无符则是63位。因为此我们能够截取的数据最多也就到64位了。当超过长度范围时会报错。

批量修改位的数值
首先我们直接设置一个key=test value=hello的一个键值对
其次将0到8位值,设为数字97的无符号二进制值,97刚刚好就是a的二进制值
最后查询一下,hello变成aello,此外更新的时候redis会把之前的值给返回104就是h的值

127.0.0.1:6379> set test hello
OK
127.0.0.1:6379> BITFIELD test set u8 0 97
1) (integer) 104
127.0.0.1:6379> get test
"aello"

另外在使用的时候需要注意几个点,无符或者有符,虽然我们在使用业务场景时不一定有负数,我们设置值的时候设置有符无符并不重要,关键是取值的时候,若是有符,则最高位是符合位。

127.0.0.1:6379> set test hello
OK
127.0.0.1:6379> BITFIELD test set i8 0 -97
1) (integer) 104
127.0.0.1:6379> BITFIELD test get i8 0
1) (integer) -97
127.0.0.1:6379> BITFIELD test get u8 0
1) (integer) 159

此外bitfields还支持多个指令的执行

127.0.0.1:6379> BITFIELD test get i8 0 get i8 8
1) (integer) -97
2) (integer) 101

下面接着位图的代码做调整,主要是新增了最下面的俩个方法

@Component
public class BitsOpUtils {

    @Autowired
    private RedisTemplate<String, String> jedisTemplate;
    
    public boolean setBits(String key, int index, int value) {
        //tag为true就是设置1  否则就是设置0
        boolean tag = value == Constants.ONE;
        return jedisTemplate.execute((RedisCallback<Boolean>) con -> con.setBit(key.getBytes(), index, tag));
    }
    
    public Long countBits(String key) {
        return jedisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
    }
    
    //一次过设置多个位
    public List<Long> setBitFields(String key, int index, int value) {
        return jedisTemplate.execute((RedisCallback<List<Long>>) con -> con.bitField(key.getBytes(),
                BitFieldSubCommands.create().set(BitFieldType.UINT_8).valueAt(index).to(value)));
    }
    
    //获取从某个位到某个位的值
    public List<Long> count(String key, int index, int limit) {
        return jedisTemplate.execute((RedisCallback<List<Long>>) con -> con.bitField(key.getBytes(),
                BitFieldSubCommands.create().get(BitFieldType.unsigned(limit)).valueAt(index)));
    }
}

简单进行测试

    @Test
    public void setMutiBits() {
        String key = "hello";
        int index = 0;
        int value = Integer.valueOf("01100001", 2);
        List<Long> result = bitsOpUtils.setBitFields(key, index, value);
        System.out.println(result);
    }

最后输出104,因为h被替换为a了,替换的时候会返回该片段的值

    @Test
    public void getBits() {
        String key = "hello";
        int index = 0;
        int limit = 8;
        List<Long> result = bitsOpUtils.count(key, index, limit);
        System.out.println(result);
    }

最后返回[97]

如果我们要模拟批量更新签到,或者是查询某个人某个连续时间段内的签到情况,那么通过上面的代码,其实也可以支持了,要做的只是将业务数据转化成入参。就不写这部分代码了。

相关文章

  • 位图的增强,bitfields

    之前有一篇文章讲了位图的使用,然后简单做了个测试,模拟了签到的场景。但是还是存在着一些问题,如果一个人一年一条签到...

  • LabVIEW色彩定位实现药品包装质量检测(实战篇—4)

    1、原理 色彩定位(Color Location)是指通过对色彩匹配功能进行增强和扩展,以快速定位图像中特定颜色区...

  • 两个位图覆盖合成为一个位图

    /** *把两个位图覆盖合成为一个位图,以底层位图的长宽为基准 *@parambackBitmap在底部的位图 *...

  • BMP位图格式解析

    一般BMP图像文件由以下4部分组成:位图文件头、位图信息头、调色板、实际的位图数据。位图文件头数据结构: 位图信息...

  • CorelDRAW位图转换矢量图

    使用CorelDRAW 软件中的快速描摹位图就是可以使位图转化为矢量图的一个过程,不过描摹位图之后,会丢掉很多位图...

  • 干货 | 非常完整的人体穴位图与功效(果断收藏)

    人体穴位作用图解大全更清晰直观的标注了各个人体穴位,包括头部穴位图、胸部穴位图、背部穴位图、胳膊手部穴位图、人体腿...

  • 位图和布隆过滤器

    位图 位图的概念 位图(bitmap)其实就是哈希表的一种特殊情况。不同的是位图是通过二进制位来表示数据是否存在。...

  • ESP8266学习:U8G2驱动OLED

    drawXBM x:X位置。y:Y位置。w:位图的宽度。h:位图的高度。bitmap:指向位图开始的指针 draw...

  • 关于一些东西

    简述矢量图和位图的区别。 答:根据存储方式的不同,电脑图形或图像可分为两大类,即位图和矢量图。 位图:位图比较适合...

  • Redis第1️⃣3️⃣课 BitMap 位图

    字母big的位图,对应上图 设置位图会触发补零操作 所以最好不要在一个很小的位图上往后很多位上设置位图。这不得不补...

网友评论

      本文标题:位图的增强,bitfields

      本文链接:https://www.haomeiwen.com/subject/rsngmktx.html