nx_bloom.nx
buildroot/runtime/nx_bloom.nx
about
bloom.nx -- Bloom filter (Burton Howard Bloom, 1970).
Probabilistic set membership: "probably present" or
"definitely absent". Uses k independent hash functions to
set k bits per insert; a query returns "absent" iff any of
k bits is unset.
Used for: cache-miss avoidance (Bigtable, Cassandra), spell-
checkers, network protocol scoping (BitTorrent peer exchange),
password leak detection (HIBP k-anonymity prefix).
Trade-off: memory + time efficient at the cost of allowing
false positives (no false negatives). For target false-
positive rate p, expected items n:
m = -n * ln(p) / (ln(2)^2) bits of bitmap
k = (m / n) * ln(2) hash functions
Caller picks (m, k) at construction.
Invariants:
BL1 False NEGATIVE rate is exactly 0. If a key was
inserted, query returns true.
BL2 False positive rate depends on (m, k, n) per the
formula above. Caller responsibility.
BL3 Capacity (cap_bits) must be a power of two so we can
mask instead of modulo. Hash bits map to bit indices
via & (cap_bits - 1).
BL4 Two hash functions are mixed via the "Kirsch-Mitzenmacher
double hashing" trick (h1 + i*h2 for i = 0..k-1) to
cheaply produce k independent-enough hashes from two.
nx_safety_envelope:
intended_use: "Bloom filter -- probabilistic set-membership
for dedup, cache lookup, malware-hash check"
sil_target: SIL1 (probabilistic; false-positive rate
is documented)
asil_target: QM
dal_target: NONE
evidence: [Bloom_1970_canonical_basis,
Kirsch_Mitzenmacher_2006_double_hashing,
sealed_verdict_enum, no_FP]
dependencies 2 imports · 3 importers
imports: nx_syscalls.nxnx_murmur3.nx
imported by: nx_bloom_capacity.nxnx_bloom_capacity_test.nxnx_ingest_runner.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 56 | struct Bloom { |
consts
| 54 | const K_MAGIC_1024: i64 = 1024 |
functions
| 63 | func bl_is_pow2(n: i64) -> i64 {
called by 1: bloom_new |
| 71 | func bloom_new(cap_bits: i64, k: i64) -> *Bloom { |
| 86 | func bl_set_bit(bf: *Bloom, bit_idx: i64) -> i64 {
called by 1: bloom_insert |
| 94 | func bl_get_bit(bf: *Bloom, bit_idx: i64) -> i64 {
called by 1: bloom_contains |
| 101 | func bloom_insert(bf: *Bloom, key: *u8, key_len: i64) -> i64 { |
| 116 | func bloom_contains(bf: *Bloom, key: *u8, key_len: i64) -> i64 { |
| 130 | func main() -> i64 { |