Bitmap工具类

阅读 24

2022-05-05

Bitmap工具类

封装StringRedisTemplate

@Component
public class BitMapUtil {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 设置key字段第offset位bit数值
     *
     * @param key    字段
     * @param offset 位置
     * @param value  数值
     */
    public void setBit(String key, long offset, boolean value) {
        stringRedisTemplate.execute((RedisCallback<?>) con -> con.setBit(key.getBytes(), offset, value));
    }

    /**
     * 判断该key字段offset位否为1
     *
     * @param key    字段
     * @param offset 位置
     *
     * @return 结果
     */
    public boolean getBit(String key, long offset) {
        return (boolean) stringRedisTemplate.execute((RedisCallback<?>) con -> con.getBit(key.getBytes(), offset));

    }

    /**
     * 统计key字段value为1的总数
     *
     * @param key 字段
     *
     * @return 总数
     */
    public Long bitCount(String key) {
        return stringRedisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
    }

    /**
     * 统计key字段value为1的总数,从start开始到end结束
     *
     * @param key   字段
     * @param start 起始
     * @param end   结束
     *
     * @return 总数
     */
    public Long bitCount(String key, Long start, Long end) {
        return (Long) stringRedisTemplate.execute((RedisCallback<?>) con -> con.bitCount(key.getBytes(), start, end));
    }

    /**
     * 取多个key并集并计算总数
     *
     * @param key key
     *
     * @return 总数
     */
    public Long opOrCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        stringRedisTemplate.execute((RedisCallback<?>) con -> con.bitOp(RedisStringCommands.BitOperation.OR, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        stringRedisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return this.bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 取多个key的交集并计算总数
     *
     * @param key key
     *
     * @return 总数
     */
    public Long opAndCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        stringRedisTemplate.execute((RedisCallback<?>) con -> con.bitOp(RedisStringCommands.BitOperation.AND, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        stringRedisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return this.bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 取多个key的补集并计算总数
     *
     * @param key key
     *
     * @return 总数
     */
    public Long opXorCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        stringRedisTemplate.execute((RedisCallback<?>) con -> con.bitOp(RedisStringCommands.BitOperation.XOR, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        stringRedisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return this.bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 取多个key的否集并计算总数
     *
     * @param key key
     *
     * @return 总数
     */
    public Long opNotCount(String... key) {
        byte[][] keys = new byte[key.length][];
        for (int i = 0; i < key.length; i++) {
            keys[i] = key[i].getBytes();
        }
        stringRedisTemplate.execute((RedisCallback<?>) con -> con.bitOp(RedisStringCommands.BitOperation.NOT, (key[0] + "To" + key[key.length - 1]).getBytes(), keys));
        stringRedisTemplate.expire(key[0] + "To" + key[key.length - 1], 10, TimeUnit.SECONDS);
        return this.bitCount(key[0] + "To" + key[key.length - 1]);
    }

    /**
     * 从第start位开始取offset位结果为无符号数的
     * 有符号数最多可以获取64位, 无符号数只能获取63位
     *
     * @param key    key
     * @param start  从第几位开始
     * @param offset 偏移量多少
     *
     * @return 取出的值
     */
    public List<Long> bitfield(String key, int start, int offset) {
        return stringRedisTemplate.execute((RedisCallback<List<Long>>) con -> con.bitField(key.getBytes(), BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(start)).valueAt(offset)));
    }
}

精彩评论(0)

0 0 举报