code wiki / (root) / nx_sketch_cpc.nx

nx_sketch_cpc.nx

buildroot/runtime/nx_sketch_cpc.nx

6971 B196 linesdepth 4pulls 7 transitivereach 1 importersview sourcekind sketch/demotopic sketch
docsdependenciesstructsconstsfunctions

about

sketch_cpc.nx -- CPC sparse-mode cardinality sketch (Lang 2017 / FM85). "Back to the Future: An Even More Nearly Optimal Cardinality Estimation Algorithm" -- arXiv:1708.06839. CPC is the headline cardinality stomp over HLL: same memory, tighter rel-stddev via the HIP estimator. THIS V1 SHIPS THE SPARSE MODE + HIP ESTIMATOR: - sparse mode: store coupons in a hash set until capacity reached - HIP estimator: kappa accumulates 1/theta on every distinct coupon DENSE MODE (pinned + sliding) queued for v2. Sparse mode alone is sufficient for cardinalities up to ~K coupons (typical K=4096 -> exact for n < ~3000, then accurate-via-HIP up to ~tens-of-thousands). COUPON DERIVATION: hash(key) -> 64-bit value column = (hash >> 32) & (m - 1) (high bits choose register column) row = clz32(hash & 0xFFFFFFFF) + 1 (low bits drive rho, capped at w) coupon_id = column * w + row (unique pair encoding) HIP ESTIMATOR (Cohen 2015, Lang 2017): For each distinct coupon arrival i (0..n-1): theta_i = (M - i) / M where M = m * w (total possible coupons) kappa += 1 / theta_i = M / (M - i) estimate = kappa At i = 0 (first coupon): theta = 1.0; kappa += 1. At i = M-1: theta = 1/M; kappa += M. COMPLEMENTS the cardinality family: - HLL/LC/KMV/Theta: classical estimators, lots of variance - CPC (this): HIP-based, near-optimal variance via online accounting COMPOSES against sketch_hash_map for sparse coupon storage. LOSSLESS-LANGUAGE DISCIPLINE: estimate has rel_stddev approx 1/sqrt(M) at confidence 0.6827. For m=128, w=32 (M=4096): ~1.56% rel. For HLL_8 lg_k=7 (m=128): ~9.2% rel. CPC stomp ~6x improvement.

dependencies 5 imports · 1 importers

nx_syscalls.nx nx_murmur3.nx nx_bits.nx nx_sketch_hash_map.nx nx_sketch_types.nx nx_sketch_cpc.nx nx_bench_hll_vs_cpc.nx

imports: nx_syscalls.nxnx_murmur3.nxnx_bits.nxnx_sketch_hash_map.nxnx_sketch_types.nx

imported by: nx_bench_hll_vs_cpc.nx

structs

60struct Cpc

consts

50const NX_MAGIC_1000000: i64 = 1000000
51const NX_MAGIC_1000000000: i64 = 1000000000
52const NX_MAGIC_682700000: i64 = 682700000
54const NX_CPC_MIN_LG_K: i64 = 4
55const NX_CPC_MAX_LG_K: i64 = 14
56const NX_CPC_WINDOW: i64 = 32 // rows per column (bits of rho)
57const NX_CPC_SEED_HI: i64 = 0x9747B28C
58const NX_CPC_SEED_LO: i64 = 0x36185EC0

functions

72func nx_cpc_clz32(x: i64) -> i64
called by 1: nx_cpc_coupon calls 1: nx_bits_clz32
81func nx_cpc_alloc(lg_k: i64, hashmap_cap: i64, seed: i64) -> *Cpc
called by 1: main calls 2: nx_hmap_allocsys_mmap
104func nx_cpc_coupon(c: *Cpc, key: *u8, len: i64) -> i64
called by 1: nx_cpc_add calls 2: murmur3_32nx_cpc_clz32
120func nx_cpc_hip_add(c: *Cpc, n_before: i64) -> i64
called by 1: nx_cpc_add
130func nx_cpc_add(c: *Cpc, key: *u8, len: i64) -> i64
144func nx_cpc_estimate(c: *Cpc) -> i64
called by 2: mainnx_cpc_query
152func nx_cpc_isqrt(x: i64) -> i64
169func nx_cpc_stddev_rel_ppb(c: *Cpc) -> i64
called by 1: nx_cpc_query calls 1: nx_cpc_isqrt
175func nx_cpc_query(c: *Cpc) -> *ApproxI64
186func nx_cpc_n_coupons(c: *Cpc) -> i64
calls 1: nx_hmap_size
190func nx_cpc_big_m(c: *Cpc) -> i64
194func nx_cpc_memory_bytes(c: *Cpc) -> i64
called by 1: main calls 1: nx_hmap_memory_bytes