布隆过滤器

package com.xiaomi.oos.xmstore.oms.controller;

import java.util.BitSet;

public class Bloom {
    private int times = 5; // 哈希次数
    private int len = 100; // 空间长度
    private long count = 64L; // 插入的元素个数
    private double rate = 0.01; // 误报率
    private BitSet bitSet;

    public Bloom() {
        this.init(10000, 0.01);
    }

    public void init(Long count, double rate) {
        this.count = count;
        this.rate = rate;
        int len = -(int) ((Math.log(rate) * count) / (Math.pow(Math.log(2), 2)));
        this.len = Math.max(len, 1);
        int times = (int) (Math.log(2) * (this.len / this.count));
        this.times = Math.max(times, 1);
        this.bitSet = new BitSet(len);
    }

    public void init(int count, double rate) {
        this.init(Long.valueOf(count), rate);
    }

    @Override
    public String toString() {
        return "元素个数:" + this.count + " 误报率:" + this.rate + " 过滤器长度:" + this.len + " 哈希次数:" + this.times;
    }

    public void add(Long id) {
        long[] pos = this.pos(id);
        for (long po : pos) {
            this.bitSet.set(Math.toIntExact(po));
        }
    }

    public void add(int id) {
        this.add(Long.valueOf(id));
    }

    public boolean find(Long id) {
        long[] pos = this.pos(id);
        for (long po : pos) {
            if (!this.bitSet.get(Math.toIntExact(po))) {
                return false;
            }
        }
        return true;
    }

    public boolean find(int id) {
        return this.find(Long.valueOf(id));
    }

    public long[] pos(long id) {
        long prev = id;
        long[] pos = new long[this.times];
        for (int i = 0; i < this.times; i++) {
            int hashCode = Math.abs(String.valueOf(prev).hashCode());
            int mod = hashCode % len;
            prev = hashCode;
            pos[i] = mod;
        }
        return pos;
    }

    public String dumpPos(long id) {
        long[] pos = this.pos(id);
        StringBuffer posS = new StringBuffer();
        for (long po : pos) {
            posS.append(po);
            posS.append(" ");
        }
        return posS.toString();
    }

    public String dumpPos(int id) {
        return this.dumpPos(Long.valueOf(id));
    }

    public static void main(String[] args) {
        Bloom bloom = new Bloom();
        bloom.init(100000, 0.01);

        System.out.println(bloom);

        System.out.println("10的hash分布:  " + bloom.dumpPos(10));

        StringBuffer added = new StringBuffer();

        for (int i = 0; i < 10; i++) {
            final int i1 = (int) (Math.random() * 10000);
            bloom.add(i1);
            added.append(i1);
            added.append(" ");
        }

        System.out.println("插入10个0-10000的随机数: " + added.toString());

        System.out.print("查找: ");
        for (int i = 0; i < 10000; i++) {
            if (bloom.find(i)) {
                System.out.print(i + " ");
            }
        }
    }
}

测试结果:

《布隆过滤器》

点赞

发表评论

邮箱地址不会被公开。 必填项已用*标注