bevy_utils/
bloom_filter.rs1use bevy_platform::hash::FixedHasher;
2use core::hash::{BuildHasher, Hash};
3
4#[derive(Clone, Copy, Debug)]
24pub struct BloomFilter<const N: usize, const K: usize = 2> {
25 bits: [u64; N],
26}
27
28impl<const N: usize, const K: usize> Default for BloomFilter<N, K> {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl<const N: usize, const K: usize> BloomFilter<N, K> {
35 pub const fn new() -> Self {
37 assert!(N > 0, "size must be at least 1");
38 Self { bits: [0; N] }
39 }
40
41 pub fn insert(&mut self, item: &impl Hash) {
43 let (h1, h2) = self.hash(item);
44 let m = (N * 64) as u64;
45 for i in 0..K {
46 let idx = (h1.wrapping_add((i as u64).wrapping_mul(h2))) % m;
47 self.bits[idx as usize / 64] |= 1 << (idx % 64);
48 }
49 }
50
51 pub fn contains(&self, item: &impl Hash) -> bool {
53 let (h1, h2) = self.hash(item);
54 let m = (N * 64) as u64;
55 for i in 0..K {
56 let idx = (h1.wrapping_add((i as u64).wrapping_mul(h2))) % m;
57 if self.bits[idx as usize / 64] & (1 << (idx % 64)) == 0 {
58 return false;
59 }
60 }
61 true
62 }
63
64 pub fn check_insert(&mut self, item: &impl Hash) -> bool {
69 let res = self.contains(item);
70 if !res {
71 self.insert(item);
72 }
73 res
74 }
75
76 fn hash(&self, item: &impl Hash) -> (u64, u64) {
77 let hash = FixedHasher.hash_one(item);
78 (hash as u32 as u64, hash >> 32)
79 }
80}