布隆过滤器使用方式

一般情况下,我们使用Redis作为布隆过滤器的内存介质,所以我们要保证当前项目能够连接到Redis才能将数据加载到布隆过滤器再进后续的操作***(window的Redis不支持Docker中的Redis支持)

  1. 添加redis依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置redis连接
spring:
  redis:
    host: 192.168.137.150
    port: 6379
    password:

3.布隆过滤器代码(因为没有相应的pom依赖所以只能将代码复制到项目中进行使用)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;

@Component
public class RedisBloomUtils {
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static RedisScript<Boolean> bfreserveScript = new DefaultRedisScript<>("return redis.call('bf.reserve', KEYS[1], ARGV[1], ARGV[2])", Boolean.class);

    private static RedisScript<Boolean> bfaddScript = new DefaultRedisScript<>("return redis.call('bf.add', KEYS[1], ARGV[1])", Boolean.class);

    private static RedisScript<Boolean> bfexistsScript = new DefaultRedisScript<>("return redis.call('bf.exists', KEYS[1], ARGV[1])", Boolean.class);

    private static String bfmaddScript = "return redis.call('bf.madd', KEYS[1], %s)";

    private static String bfmexistsScript = "return redis.call('bf.mexists', KEYS[1], %s)";

    public Boolean hasBloomFilter(String key){
        return redisTemplate.hasKey(key);
    }
    /**
     * 设置错误率和大小(需要在添加元素前调用,若已存在元素,则会报错)
     * 错误率越低,需要的空间越大
     * @param key
     * @param errorRate 错误率,默认0.01
     * @param initialSize 默认100,预计放入的元素数量,当实际数量超出这个数值时,误判率会上升,尽量估计一个准确数值再加上一定的冗余空间
     * @return
     */
    public Boolean bfreserve(String key, double errorRate, int initialSize){
        return redisTemplate.execute(bfreserveScript, Arrays.asList(key), String.valueOf(errorRate), String.valueOf(initialSize));
    }

    /**
     * 添加元素
     * @param key
     * @param value
     * @return true表示添加成功,false表示添加失败(存在时会返回false)
     */
    public Boolean bfadd(String key, String value){
        return redisTemplate.execute(bfaddScript, Arrays.asList(key), value);
    }

    /**
     * 查看元素是否存在(判断为存在时有可能是误判,不存在是一定不存在)
     * @param key
     * @param value
     * @return true表示存在,false表示不存在
     */
    public Boolean bfexists(String key, String value){
        return redisTemplate.execute(bfexistsScript, Arrays.asList(key), value);
    }

    /**
     * 批量添加元素
     * @param key
     * @param values
     * @return 按序 1表示添加成功,0表示添加失败
     */
    public List<Integer> bfmadd(String key, String... values){
        return (List<Integer>)redisTemplate.execute(this.generateScript(bfmaddScript, values), Arrays.asList(key), values);
    }

    /**
     * 批量检查元素是否存在(判断为存在时有可能是误判,不存在是一定不存在)
     * @param key
     * @param values
     * @return 按序 1表示存在,0表示不存在
     */
    public List<Integer> bfmexists(String key, String... values){
        return (List<Integer>)redisTemplate.execute(this.generateScript(bfmexistsScript, values), Arrays.asList(key), values);
    }

    private RedisScript<List> generateScript(String script, String[] values) {
        StringBuilder sb = new StringBuilder();
        for(int i = 1; i <= values.length; i ++){
            if(i != 1){
                sb.append(",");
            }
            sb.append("ARGV[").append(i).append("]");
        }
        return new DefaultRedisScript<>(String.format(script, sb.toString()), List.class);
    }

}

4.使用方式: 因为布隆过滤器上面添加了@Component注解所以当前类会被spring进行管理,我们使用依赖注入的方式使用即可

public class RedisBloomUtilsDemo {
    @Autowired
    private RedisBloomUtils redisBloomUtils;
    @Override
    public void Demo() {
        // 先将要添加到布隆过滤器的元素保存在一个数组中
        String[] colors={"red","origin","yellow","green","blue","pink"};
        // 将上面的集合中的元素批量新增到布隆过滤器中
        redisBloomUtils.bfmadd("color",colors);
        // 定义一个要判断是否在集合中的元素
        String elm="black";
        System.out.println("布隆过滤器判断"+elm+"是否在集合中:"+redisBloomUtils.bfexists("color",elm));
    }
}
posted @   Seasky-null  阅读(331)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
点击右上角即可分享
微信分享提示