sketch_cpc_dense_test.nx source
↩ module page · 137 lines · 3981 B
1// sketch_cpc_dense_test.nx -- CPC dense-mode verification.
2
3import "syscalls.nx"
4import "sketch_cpc_dense.nx"
5import "sketch_types.nx"
6
7func iabs(x: i64) -> i64 {
8 if x < 0 { return -x }
9 return x
10}
11
12func main() -> i64 {
13 // ---- alloc ----
14 // lg_k=5 (m=32), w=32 -> big_M = 1024. Bitmap = 128 bytes.
15 let c: *CpcDense = nx_cpcd_alloc(5, 32, 42)
16 if c == (0 as *CpcDense) { return __syscall(93, 5, 0, 0, 0, 0, 0) }
17 if nx_cpcd_alloc(1, 32, 1) != (0 as *CpcDense) {
18 return __syscall(93, 6, 0, 0, 0, 0, 0)
19 }
20 if nx_cpcd_alloc(5, 100, 1) != (0 as *CpcDense) {
21 return __syscall(93, 7, 0, 0, 0, 0, 0)
22 }
23 if nx_cpcd_big_m(c) != 1024 {
24 return __syscall(93, 8, 0, 0, 0, 0, 0)
25 }
26 // 128 bytes bitmap + 72 header = 200 bytes total.
27 if nx_cpcd_memory_bytes(c) != 200 {
28 return __syscall(93, 9, 0, 0, 0, 0, 0)
29 }
30
31 // ---- empty: estimate = 0 ----
32 if nx_cpcd_estimate(c) != 0 {
33 return __syscall(93, 10, 0, 0, 0, 0, 0)
34 }
35
36 // ---- single insertion: HIP estimate = 1 ----
37 nx_cpcd_add(c, "alice", 5)
38 if nx_cpcd_estimate(c) != 1 {
39 return __syscall(93, 20, 0, 0, 0, 0, 0)
40 }
41 if nx_cpcd_n_set(c) != 1 {
42 return __syscall(93, 21, 0, 0, 0, 0, 0)
43 }
44
45 // ---- 100 distinct: estimate ~ 100 ----
46 let c2: *CpcDense = nx_cpcd_alloc(5, 32, 7)
47 let buf: *u8 = sys_mmap(8)
48 var i: i64 = 0
49 while i < 100 {
50 buf[0] = (i ) & 0xFF
51 buf[1] = (i >> 8 ) & 0xFF
52 buf[2] = 0x30
53 buf[3] = 0
54 buf[4] = 0
55 buf[5] = 0
56 buf[6] = 0
57 buf[7] = 0
58 nx_cpcd_add(c2, buf, 8)
59 i = i + 1
60 }
61 let e100: i64 = nx_cpcd_estimate(c2)
62 // big_M=1024 -> stddev ~3.1%. Allow +/-15.
63 if iabs(e100 - 100) > 15 {
64 return __syscall(93, 30, 0, 0, 0, 0, 0)
65 }
66
67 // ---- idempotent inserts ----
68 let c3: *CpcDense = nx_cpcd_alloc(5, 32, 1)
69 nx_cpcd_add(c3, "x", 1)
70 nx_cpcd_add(c3, "x", 1)
71 nx_cpcd_add(c3, "x", 1)
72 if nx_cpcd_n_set(c3) != 1 {
73 return __syscall(93, 40, 0, 0, 0, 0, 0)
74 }
75 if nx_cpcd_estimate(c3) != 1 {
76 return __syscall(93, 41, 0, 0, 0, 0, 0)
77 }
78
79 // ---- typed envelope ----
80 let q: *ApproxI64 = nx_cpcd_query(c2)
81 if q.envelope_kind != NX_ENV_REL_STDDEV {
82 return __syscall(93, 50, 0, 0, 0, 0, 0)
83 }
84 // big_M=1024 -> isqrt(1024)=32 -> stddev_ppb = 1e9/32 = 31_250_000.
85 if iabs(q.param_a - 31250000) > 1000 {
86 return __syscall(93, 51, 0, 0, 0, 0, 0)
87 }
88 if q.maturity != NX_MATURITY_PRODUCTION {
89 return __syscall(93, 52, 0, 0, 0, 0, 0)
90 }
91
92 // ---- merge ----
93 let m_a: *CpcDense = nx_cpcd_alloc(5, 32, 99)
94 let m_b: *CpcDense = nx_cpcd_alloc(5, 32, 99)
95 i = 0
96 while i < 50 {
97 buf[0] = (i ) & 0xFF
98 buf[1] = (i >> 8 ) & 0xFF
99 buf[2] = 0x80
100 buf[3] = 0
101 buf[4] = 0
102 buf[5] = 0
103 buf[6] = 0
104 buf[7] = 0
105 nx_cpcd_add(m_a, buf, 8)
106 i = i + 1
107 }
108 i = 50
109 while i < 100 {
110 buf[0] = (i ) & 0xFF
111 buf[1] = (i >> 8 ) & 0xFF
112 buf[2] = 0x80
113 buf[3] = 0
114 buf[4] = 0
115 buf[5] = 0
116 buf[6] = 0
117 buf[7] = 0
118 nx_cpcd_add(m_b, buf, 8)
119 i = i + 1
120 }
121 let merged: *CpcDense = nx_cpcd_merge(m_a, m_b)
122 if merged == (0 as *CpcDense) {
123 return __syscall(93, 60, 0, 0, 0, 0, 0)
124 }
125 let e_merged: i64 = nx_cpcd_estimate(merged)
126 // True cardinality of union = 100. Allow +/-15.
127 if iabs(e_merged - 100) > 15 {
128 return __syscall(93, 61, 0, 0, 0, 0, 0)
129 }
130 // Mismatched seed -> NULL.
131 let m_c: *CpcDense = nx_cpcd_alloc(5, 32, 88)
132 if nx_cpcd_merge(m_a, m_c) != (0 as *CpcDense) {
133 return __syscall(93, 62, 0, 0, 0, 0, 0)
134 }
135
136 return 0
137}