Skip to main content

amadeus_runtime/consensus/bic/
sol_bloom.rs

1#[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); // lengths match by construction
27            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}