amadeus_runtime/consensus/bic/
sol_bloom.rs1#[allow(dead_code)]
2use amadeus_utils::blake3::Hasher;
3
4pub const PAGES: u64 = 256;
5pub const PAGE_SIZE: u64 = 65_536;
6pub const M: u64 = PAGES * PAGE_SIZE;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct Seg {
10 pub page: u64,
11 pub bit_offset: u64,
12}
13
14#[inline]
15pub fn simulate_fpr(n: f64, m: f64, k: f64) -> f64 {
16 assert!(n > 0.0 && m > 0.0 && k > 0.0, "n, m, k must be > 0");
17 (1.0 - (-k * n / m).exp()).powf(k)
18}
19
20#[inline]
21fn indices_from_digest(digest: &[u8]) -> Vec<u64> {
22 digest
23 .rchunks_exact(16)
24 .map(|chunk| {
25 let mut buf = [0u8; 16];
26 buf.copy_from_slice(chunk); let word = u128::from_le_bytes(buf);
28 (word % (M as u128)) as u64
29 })
30 .collect()
31}
32
33#[inline]
34pub fn hash_to_indices(bin: &[u8]) -> Vec<u64> {
35 let mut hasher = Hasher::new();
36 hasher.update(bin);
37 let digest = hasher.finalize();
38 indices_from_digest(&digest)
39}
40
41#[inline]
42pub fn segs_from_digest(digest: &[u8]) -> Vec<Seg> {
43 let idxs = indices_from_digest(digest);
44 idxs.into_iter().map(|idx| Seg { page: (idx / PAGE_SIZE), bit_offset: (idx % PAGE_SIZE) }).collect()
45}
46
47#[inline]
48pub fn hash(bin: &[u8]) -> Vec<u64> {
49 hash_to_indices(bin)
50}
51
52#[inline]
53pub fn segs(digest: &[u8]) -> Vec<Seg> {
54 segs_from_digest(digest)
55}