首页 > 其他分享 >Bloom Filter概念和实现原理

Bloom Filter概念和实现原理

时间:2022-10-18 14:00:52浏览次数:77  
标签:元素 System Filter 数据量 println 原理 Bloom

Bloom Filter概念和实现原理

背景

我们在判断某一个元素是否在某个集合里面时,一般是将集合里面的所有元素都保存下来,然后直接读取磁盘上的数据再进行判断,但是如果数据量很大,此时读取速度就会降低,这时我们可以将数据提前存储到内存中,内存读取速度会快很多,但是数据量在逐渐增大时,内存的开销也在逐渐增大,检索的时间也会变长。此时,在数据量特别大的情况下,需要一个时间和空间上都具有优势的数据结构。

介绍

Bloom Filter是由Howard Bloom在1970年提出的二进制向量数据结构,它具有较好的时间和空间效率,用来检测一个元素是否在某个集合中,但是缺点是,有一定的错误率和删除困难。

原理

Bloom Filter判断某一个元素是否在集合中时,会将集合中的每一个元素都通过K个不同的Hash函数映射到一个bit数组里面的K个点,每个点设置为1。此时检索一个元素时,只需要将该元素同样进行K个不同的Hash函数,求得K个点位,如果这K个点位全部是1,则代表元素可能在集合里面,如果有一个为0,则代表元素不在集合里面。

image-20221010141654427

公式

  1. Bit数组大小的计算

    需要根据预估的数据量n以及错误率p来计算Bit数组的大小m:
    $$
    m=- \frac {n \ln {p}} {(\ln {2})^2}
    $$

  2. Hash函数个数k计算

    根据预估的数据量n和已经求得的Bit数组长度m,可以计算出Hash函数的个数k:
    $$
    k=\frac {m} {n} \ln {2}
    $$

代码实现

/**
 * All rights Reserved, Designed By monkey.blog.xpyvip.top
 *
 * @version V1.0
 * @Package PACKAGE_NAME
 * @Description:
 * @Author: xpy
 * @Date: Created in 2022年10月09日 4:42 下午
 */
public class Test {
    public static void main(String[] args) {
        System.out.println(calNumOfBits(3,0.1));
        System.out.println(calNumOfHashFuns(3, 14));
    }

    /**
     * 计算bit数组大小m
     * @param n 预估的数据量
     * @param p 错误率 在0-1之间 0<p<1
     * @return
     */
    private static long calNumOfBits(long n, double p){
        if(p == 0){
            p = Double.MIN_VALUE;
        }
        return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));
    }

    /**
     * 计算最佳需要多少个hash函数,即k值
     * @param n 预估的数据量
     * @param m bit数组大小m
     * @return
     */
    private static int calNumOfHashFuns(long n, long m){
        return  Math.max(1, (int) Math.round((double) m / n * Math.log(2)));
    }
}

实际Bloom Filter使用

  1. 使用hutool里面的Bloom Filter

    /**
     * All rights Reserved, Designed By monkey.blog.xpyvip.top
     *
     * @version V1.0
     * @Package PACKAGE_NAME
     * @Description:
     * @Author: xpy
     * @Date: Created in 2022年10月09日 4:42 下午
     */
    public class Test {
        public static void main(String[] args) {
            BitMapBloomFilter bitMapBloomFilter = new BitMapBloomFilter(8);
            bitMapBloomFilter.add("test123");
            bitMapBloomFilter.add("tset123456");
            System.out.println(bitMapBloomFilter.contains("test123"));
            System.out.println(bitMapBloomFilter.contains("test12"));
        }
    }
    
  2. 使用Google的guava包

    import com.google.common.hash.BloomFilter;
    import com.google.common.hash.Funnels;
    
    import java.nio.charset.Charset;
    
    /**
     * All rights Reserved, Designed By monkey.blog.xpyvip.top
     *
     * @version V1.0
     * @Package PACKAGE_NAME
     * @Description:
     * @Author: xpy
     * @Date: Created in 2022年10月09日 4:42 下午
     */
    public class Test {
        public static void main(String[] args) {
            // 设置预估的数据量在1000000,错误率在0.01
            BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 1000000, 0.01);
            bloomFilter.put("test123");
            bloomFilter.put("test123456");
            bloomFilter.put("tset123456");
            System.out.println(bloomFilter.mightContain("test123456"));
            System.out.println(bloomFilter.mightContain("tset12"));
        }
    }
    

扩展

  1. 错误率

    Bloom Filter存在判断错误的情况,适用于允许存在判断错误的场景。

  2. 不允许删除

    删除其中某一个元素,需要将该元素对应的bit位设置为0,但是很可能有其他元素对应,所以不能删除,设置为0。

原文链接:https://monkey.blog.xpyvip.top/archives/bloomfilter-gai-nian-he-shi-xian-yuan-li

标签:元素,System,Filter,数据量,println,原理,Bloom
From: https://www.cnblogs.com/aibianchengya/p/16802300.html

相关文章

  • 索引最左前缀原则原理
    比如有一个联合索引(name,age,porstion)底层是将三个字段的数据放到一起来进行排序首先会通过最左边的字段即name进行排序,生成B+树,当name字段相同时则会通过下一个字段age......
  • 面试官:“年轻人,我看你很懂setState原理,你来说说是同步还是异步的?”
    这一次,我将带你一次性搞懂React中常见的setState原理。setState本身的默认行为在进入主题之前,你肯定需要先学会React的基本使用。如果不会,请点赞离开;如果会用React......
  • 智能振弦传感器的参数智能识别技术原理
    智能振弦传感器的参数智能识别技术原理河北稳控科技在2020年就开始研发出智能振弦传感器电子标签专用读数模块模块TR01,最早应用到手持振弦采集仪VH03型上面,并申请获得了两......
  • Kubernetes 控制器管理器的工作原理
    在KubernetesMaster节点中,有三个重要的组件:ApiServer、ControllerManager和Scheduler,它们共同负责整个集群的管理。在本文中,我们尝试梳理一下ControllerManager的工作......
  • mysql事务隔离级别及MVCC 原理
    一、事务的隔离级别为了保证事务与事务之间的修改操作不会互相影响,innodb希望不同的事务是隔离的执行的,互不干扰。两个并发的事务在执行过程中有读读、读写(一个事务在读......
  • 驱动开发:内核枚举Minifilter微过滤驱动
    Minifilter是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微......
  • ULID规范解读与实现原理
    前提最近发现各个频道推荐了很多ULID相关文章,这里对ULID的规范文件进行解读,并且基于Java语言自行实现ULID,通过此实现过程展示ULID的底层原理。ULID出现的背景ULID全称......
  • 基于深度学习的人脸识别系统——原理篇
    1.深度学习的基本原理深度学习的起源最早可以追溯到感知机,所谓的感知机即只有一个神经元的单层神经网络,它只能完成一个简单的线性分类任务,而要解决非线性的任务,一是......
  • 浅谈区块链应用中的密码学原理
    你印象中的区块链是什么?比特币、以太坊等加密货币?这样的理解是片面的,可以这么说比特币是区块链最成功的应用。当然基于区块链的去中心化共识的应用层出不穷,下面将举几个应......
  • go channel原理及使用场景
    ​​gochannel原理及使用场景​​源码解析typehchanstruct{qcountuint//Channel中的元素个数dataqsizuint//Channel中的循环队列的......