ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手撸布隆过滤器

2021-12-21 23:30:30  阅读:141  来源: 互联网

标签:下标 int 布隆 filter key 过滤器 hash public


一个低配版BloomFilter

public class MyBloomFilter {
    // 后面hash函数会用到,用来生成不同的hash值,可以随便给,但别给奇数
    private final int[] ints = {6, 8, 16, 38, 58, 68};
    // 统计当前对象数量
    private Integer currentBeanCount = 0;
    // 你的布隆过滤器容量
    private int DEFAULT_SIZE = Integer.MAX_VALUE;
    // bit数组,用来存放结果
    private final BitSet bitSet = new BitSet(DEFAULT_SIZE);

    public MyBloomFilter() {
    }

    public MyBloomFilter(int size) {
        if (size > Integer.MAX_VALUE) throw new RuntimeException("size is too large");
        if (size <= (2 << 8)) throw new RuntimeException("size is too small");
        DEFAULT_SIZE = size;
    }
	
	// 获取当前过滤器的对象数量
    public Integer getCurrentBeanCount() {
        return currentBeanCount;
    }

    // 计算出key的hash值,并将对应下标置为1
    public void push(Object key) {
        Arrays.stream(ints).forEach(i -> bitSet.set(hash(key, i)));
        currentBeanCount++;
    }

    // 判断key是否存在,true不一定说明key存在,但是false一定说明不存在
    public boolean contain(Object key) {
        boolean result = true;
        for (int i : ints) {
            result = result && bitSet.get(hash(key, i));
        }
        return result;
    }

    // hash算法,借鉴了hashmap的算法,利用i对同个key生成一组不同的hash值
    private int hash(Object key, int i) {
        int h;
        int index = key == null ? 0 : (DEFAULT_SIZE - 1 - i) & ((h = key.hashCode()) ^ (h >>> 16));
        return index > 0 ? index : -index;
    }
}

它在用作判断对象 是否存在 时有误判率,误判率随着对象数量增加而增加
但是用作判断对象 是否不存在 时,没有误判率

一亿条数据去重

    public static void main(String[] args) {
        //实例化
        MyBloomFilter filter = new MyBloomFilter();
        for (int i = 0; i < 20; i++) {
            //push到BloomFilter
            getPersonList(500000).forEach(person -> filter.push(person));
        }
        //push一个确定的对象
        filter.push(getFixedPerson(now));
        //判断这个对象是否存在
        long start = System.currentTimeMillis();
        System.out.println(filter.contain(getFixedPerson(now)));
        long end = System.currentTimeMillis() - start;
        System.out.println("bloomFilter内对象数量:" + filter.getCurrentBeanCount());
        System.out.println("耗时(ms):" + end + ",消耗内存(M):" + (ObjectSizeCalculator.getObjectSize(filter) / (1024 * 1024)));
    }

原理

       就是通过对比hash算法计算出来的下标,但注意,是对比一组,而不是一次,一次hash结果只对应一个下标

       把同一个key进行多次hash运算,将hash出来的下标放入数组,数组默认全为0,放入元素后该下标就为1,后面判断是否存在元素的时候也是进行同样次数的hash运算,看下结果对应的所有下标是否全为1,若全为1,则代表该key可能存在,若存在不为1的,则说明该key一定不存在;

默认bit数组:[0,0,0,0,0,0]
比方说有个key计算出的一组hash下标是0,2,5
对应位bit数组:[1,0,1,0,0,1]
判断某个未知key是否存在时候,假设我们计算出来的下标是0,2,4
对应位数组:[1,0,1,0,1,0]
此时位数组内5对应下标值为0,而已知key位数组的5对应下标位1,说明这两个key一定不同

       相反,如果某个key计算出来的下标为[1,0,1,0,0,1],只能说这个key可能存在,因为这几个位置可能是其它key计算出来的


       摘自:https://blog.csdn.net/qq_33709582/article/details/122046773

标签:下标,int,布隆,filter,key,过滤器,hash,public
来源: https://blog.csdn.net/xuguangyuansh/article/details/122075608

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有