nx_stream_picker_test.nx source
↩ module page · 80 lines · 3897 B
1// nx_stream_picker_test.nx -- KAT for the streaming + endgame piece picker.
2// Native sovereign lane; exit 0 = pass, N = assertion N failed.
3
4import "nx_str.nx"
5import "nx_stream_picker.nx"
6
7func main() -> i64 {
8 let have: *i64 = sys_mmap(8 * 8) as *i64
9 let av: *i64 = sys_mmap(8 * 8) as *i64
10
11 // ---- sequential: lowest-index needed ----
12 // have [1,1,0,1,0] -> first needed = 2
13 have[0]=1; have[1]=1; have[2]=0; have[3]=1; have[4]=0
14 if nx_sp_sequential(have, 5) != 2 { return 1 }
15 // all have -> -1
16 have[2]=1; have[4]=1
17 if nx_sp_sequential(have, 5) != (0 - 1) { return 2 }
18
19 // ---- stream pick: deadline window first ----
20 // n=6, playhead=2, window=2 -> window [2,4); have [1,1,0,0,0,0], avail all>0
21 // earliest unmet+available in window = 2
22 have[0]=1; have[1]=1; have[2]=0; have[3]=0; have[4]=0; have[5]=0
23 av[0]=3; av[1]=1; av[2]=2; av[3]=5; av[4]=4; av[5]=1
24 if nx_sp_stream_pick(av, have, 6, 2, 2) != 2 { return 3 }
25 // window satisfied (have 2,3) -> fall back to rarest over needed {4,5}: av[4]=4, av[5]=1 -> 5
26 have[2]=1; have[3]=1
27 if nx_sp_stream_pick(av, have, 6, 2, 2) != 5 { return 4 }
28 // window piece needed but availability 0 -> skip in window, fall back to rarest
29 // have [1,1,0,1,1,1] (only piece 2 needed), av[2]=0 -> rarest over needed{2} but av 0 -> -1
30 have[0]=1; have[1]=1; have[2]=0; have[3]=1; have[4]=1; have[5]=1
31 av[2]=0
32 if nx_sp_stream_pick(av, have, 6, 2, 1) != (0 - 1) { return 5 }
33 // window clamps past n: playhead=5, window=10 -> window [5,6); piece5 have -> fallback rarest
34 // needed = {2}, av[2]=0 -> -1
35 if nx_sp_stream_pick(av, have, 6, 5, 10) != (0 - 1) { return 6 }
36
37 // ---- urgency ----
38 // piece 5 in [4, 4+3) = [4,7) -> urgent
39 if nx_sp_is_urgent(5, 4, 3) != 1 { return 7 }
40 // piece 8 past panic window -> not urgent
41 if nx_sp_is_urgent(8, 4, 3) != 0 { return 8 }
42 // piece 3 already behind playhead 4 -> not urgent
43 if nx_sp_is_urgent(3, 4, 3) != 0 { return 9 }
44
45 // ---- contiguous have / can play ----
46 // have [1,1,1,0,1]
47 have[0]=1; have[1]=1; have[2]=1; have[3]=0; have[4]=1
48 if nx_sp_contiguous_have(have, 5, 0) != 3 { return 10 } // 0,1,2 then gap
49 if nx_sp_contiguous_have(have, 5, 1) != 2 { return 11 } // 1,2 then gap
50 if nx_sp_contiguous_have(have, 5, 3) != 0 { return 12 } // gap at 3
51 if nx_sp_can_play(have, 5, 0, 3) != 1 { return 13 } // 3 contiguous >= 3
52 if nx_sp_can_play(have, 5, 0, 4) != 0 { return 14 } // only 3 < 4
53
54 // ---- endgame detection ----
55 if nx_sp_in_endgame(20, 20) != 1 { return 15 } // boundary inclusive
56 if nx_sp_in_endgame(21, 20) != 0 { return 16 }
57
58 // ---- block state: outstanding + pick ----
59 let bs: *i64 = sys_mmap(8 * 8) as *i64
60 // state [RECEIVED, REQUESTED, NEEDED, RECEIVED, NEEDED]
61 bs[0]=2; bs[1]=1; bs[2]=0; bs[3]=2; bs[4]=0
62 if nx_sp_blocks_outstanding(bs, 5) != 3 { return 17 } // indices 1,2,4 not received
63 if nx_sp_pick_block(bs, 5, 0) != 2 { return 18 } // normal -> first NEEDED = 2
64 // no NEEDED left: [RECEIVED, REQUESTED, REQUESTED, RECEIVED]
65 bs[0]=2; bs[1]=1; bs[2]=1; bs[3]=2
66 if nx_sp_pick_block(bs, 4, 0) != (0 - 1) { return 19 } // normal -> nothing
67 if nx_sp_pick_block(bs, 4, 1) != 1 { return 20 } // endgame -> re-race REQUESTED 1
68
69 // ---- pipeline depth (BDP) ----
70 // 10 Mbit/s = 1_250_000 B/s, rtt 100ms, 16 KiB: bdp=125000, ceil(125000/16384)=8
71 if nx_sp_pipeline_depth(1250000, 100, 16384) != 8 { return 21 }
72 // tiny pipe clamps to MIN(2)
73 if nx_sp_pipeline_depth(1000, 10, 16384) != 2 { return 22 }
74 // huge pipe clamps to MAX(256)
75 if nx_sp_pipeline_depth(1000000000, 200, 16384) != 256 { return 23 }
76 // degenerate block size -> MIN
77 if nx_sp_pipeline_depth(1250000, 100, 0) != 2 { return 24 }
78
79 return 0
80}