code wiki / (root) / sketch_cpc.nx

sketch_cpc.nx

buildroot/runtime/sketch_cpc.nx

6779 B188 linesdepth 5pulls 7 transitivereach 2 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 · 2 importers

syscalls.nx murmur3.nx nx_bits.nx sketch_hash_map.nx sketch_types.nx sketch_cpc.nx bench_hll_vs_cpc.nx sketch_cpc_test.nx

imports: syscalls.nxmurmur3.nxnx_bits.nxsketch_hash_map.nxsketch_types.nx

imported by: bench_hll_vs_cpc.nxsketch_cpc_test.nx

structs

51struct Cpc {

consts

45const NX_CPC_MIN_LG_K: i64 = 4
46const NX_CPC_MAX_LG_K: i64 = 14
47const NX_CPC_WINDOW: i64 = 32 // rows per column (bits of rho)
48const NX_CPC_SEED_HI: i64 = 0x9747B28C
49const NX_CPC_SEED_LO: i64 = 0x36185EC0

functions

64func nx_cpc_clz32(x: i64) -> i64 {
called by 1: nx_cpc_coupon calls 1: nx_bits_clz32
73func nx_cpc_alloc(lg_k: i64, hashmap_cap: i64, seed: i64) -> *Cpc {
called by 2: mainmain calls 1: nx_hmap_alloc
96func nx_cpc_coupon(c: *Cpc, key: *u8, len: i64) -> i64 {
called by 1: nx_cpc_add calls 2: murmur3_32nx_cpc_clz32
112func nx_cpc_hip_add(c: *Cpc, n_before: i64) -> i64 {
called by 1: nx_cpc_add
122func nx_cpc_add(c: *Cpc, key: *u8, len: i64) -> i64 {
136func nx_cpc_estimate(c: *Cpc) -> i64 {
144func nx_cpc_isqrt(x: i64) -> i64 {
161func nx_cpc_stddev_rel_ppb(c: *Cpc) -> i64 {
called by 1: nx_cpc_query calls 1: nx_cpc_isqrt
167func nx_cpc_query(c: *Cpc) -> *ApproxI64 {
178func nx_cpc_n_coupons(c: *Cpc) -> i64 {
called by 1: main calls 1: nx_hmap_size
182func nx_cpc_big_m(c: *Cpc) -> i64 {
called by 1: main
186func nx_cpc_memory_bytes(c: *Cpc) -> i64 {
called by 1: main calls 1: nx_hmap_memory_bytes