• 对Redis布隆过滤器的实现


    目录

     实现思路

    首先最重要的自定义hash()

    然后就是将key放入bitSet

    然后就是判断布隆过滤器bitSet数组中是否含有对应的key

    代码


     

     实现思路

    (39条消息) Redis布隆过滤器_Fairy要carry的博客-CSDN博客

    首先最重要的自定义hash()

    1.首先判断key是否为null,否则返回0——>2.然后数组长度-1-i(目的使散列均匀,因为我们定义一个数组,全是辅助多次hash,所以需要-i保留特点),然后就是(size-1-i)&((h=key.hashcode())^h>>>16)——>3.非常关键在这里,计算key的hash值后,然后^key的hash>>>16,目的是保留key的特点,保证散列均匀,因为size-1-i(像hashMap默认size为16,那么15对应的二进制为1111,那么就只能与hash的低位四个进行运算,那么保留特点就很少),所以>>>16保留了key hash低位16的特点,然后再^key.hashCode()->保证了高位16的特点(这样就保证了key的特点)

    1. private int hash(Object key, int i) {
    2. int h;
    3. //BloomFilter_Size-i归根结底是为了保证散列均匀,保证每一次hash后key的特点——>之前push也是对key进行多次hash
    4. int index = key == null ? 0 : (BloomFilter_Size - 1 - i) & ((h = key.hashCode()) ^ (h >>> 16));
    5. return index > 0 ? index : -index;
    6. }

    然后就是将key放入bitSet

    思路:1.计算key的hash(利用辅助hash数组对key进行多次hash),得到位置index后放入数组

    1. /**
    2. * 2.存放key
    3. * 思路:1.遍历布隆过滤器的hash数组,对key进行多次hash并且保存在BitSet数组中
    4. *
    5. * @param key
    6. */
    7. public void push(Object key) {
    8. Arrays.stream(HelperBloom).forEach(i -> bitSet.set(hash(key, i)));
    9. currentBaseBean++;
    10. }

    然后就是判断布隆过滤器bitSet数组中是否含有对应的key

    思路:1.一样的,这里巧妙的是利用了&&,因为我们对key进行了多次hash,所以我们遍历辅助hash数组进行多次hash,根据对应index位置从bitSet取出看是否能取出,若为false,那么后面全为false——>2.直接利用&&,result默认为true,&&有一个为false那么结果就是false

    1. /**
    2. * 3.计算key的hash值并且去bitSet寻找看是否有位置,如果有返回true
    3. * 思路:利用&&,从bitSet取出对应key的hash的index,如果没有返回false,因为&&所以结果false
    4. *
    5. * @param key
    6. * @return
    7. */
    8. public boolean isContain(Object key) {
    9. boolean result=true;
    10. for (int i : HelperBloom) {
    11. result = result && bitSet.get(hash(key, i));
    12. }
    13. return result;
    14. }

    代码

    1. import java.util.Arrays;
    2. import java.util.BitSet;
    3. /**
    4. * @author diao 2022/9/7
    5. */
    6. public class BloomFilter {
    7. //后面hash函数会用到,用来生成不同的hash值,可以随便给,但别给奇数
    8. private final int[] ints = {6, 8, 16, 38, 58, 68};
    9. private Integer currentBeanCount = 0;
    10. //你的布隆过滤器容量
    11. private int DEFAULT_SIZE = Integer.MAX_VALUE;
    12. //bit数组,用来存放结果
    13. private final BitSet bitSet = new BitSet(DEFAULT_SIZE);
    14. public BloomFilter() {
    15. }
    16. public BloomFilter(int size) {
    17. if (size <= (2 << 8)) {
    18. throw new RuntimeException("size is too small");
    19. }
    20. DEFAULT_SIZE = size;
    21. }
    22. //获取当前过滤器的对象数量
    23. public Integer getCurrentBeanCount() {
    24. return currentBeanCount;
    25. }
    26. //计算出key的hash值,并将对应下标置为true
    27. public void push(Object key) {
    28. for (int i : ints) {
    29. bitSet.set(hash(key, i));
    30. }
    31. currentBeanCount++;
    32. }
    33. //判断key是否存在,true不一定说明key存在,但是false一定说明不存在
    34. public boolean contain(Object key) {
    35. boolean result = true;
    36. for (int i : ints) {
    37. result = result && bitSet.get(hash(key, i));
    38. }
    39. return result;
    40. }
    41. //hash算法,借鉴了hashmap的算法
    42. private int hash(Object key, int i) {
    43. int h;
    44. int index = key == null ? 0 : (DEFAULT_SIZE - 1 - i) & ((h = key.hashCode()) ^ (h >>> 16));
    45. return index > 0 ? index : -index;
    46. }
    47. public static void main(String[] args) {
    48. BloomFilter bf = new BloomFilter ();
    49. bf.push("张学友");
    50. bf.push("郭德纲");
    51. bf.push("特雷杨");
    52. bf.push(666);
    53. System.out.println(bf.contain("张学友"));//true
    54. System.out.println(bf.contain("张学友 "));//false
    55. System.out.println(bf.contain("张学友1"));//false
    56. System.out.println(bf.contain("郭德纲"));//true
    57. System.out.println(bf.contain("老鹰特雷杨8"));//false
    58. System.out.println(bf.contain(666));//true
    59. System.out.println(bf.contain(888));//false
    60. }
    61. }

     

  • 相关阅读:
    第四代管网水位监测仪:高精度管网水位监测仪推荐
    Python性能测试框架Locust实战教程!
    Spring目录结构和基础JAR包介绍
    【牛客算法-二分查找】刷题和面试兼顾还得看你啊
    数学推理题:张王李赵陈五对夫妇聚会,见面握手
    mfc140u.dll丢失怎么修复?4种亲测有效的方法分享
    NumPy(二)
    什么是自我接纳?如何提高自我接纳度?
    什么是身份证ocr识别?身份证ocr识别接口API能干什么?
    [附源码]Python计算机毕业设计Django松林小区疫情防控信息管理系统
  • 原文地址:https://blog.csdn.net/weixin_57128596/article/details/126739447