Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

render_example_test.gno

3.51 Kb · 93 lines
 1package fenwickdemo
 2
 3// ExampleRender pins the realm Render output as a testable example.
 4//
 5// The block below is copied verbatim from what gno printed, never hand
 6// typed: every figure in it is computed by the library under test, so a
 7// change in the tree shows up here as a diff rather than as prose.
 8func ExampleRender() {
 9	print(Render(""))
10	// Output:
11	// # Fenwick tree
12	//
13	// A Binary Indexed Tree: prefix sums and point updates both in `O(log n)`, demoing the [`p/moul/x/daily/fenwick`](/p/nym-moultest123/x/daily/fenwick/v0) library.
14	//
15	// ## The values
16	//
17	// `3, 1, 4, 1, 5, 9, 2, 6` — 8 slots totalling `31`.
18	//
19	// ## Prefix sums
20	//
21	// | i | value | Prefix(i+1) |
22	// | --- | --- | --- |
23	// | 0 | 3 | 3 |
24	// | 1 | 1 | 4 |
25	// | 2 | 4 | 8 |
26	// | 3 | 1 | 9 |
27	// | 4 | 5 | 14 |
28	// | 5 | 9 | 23 |
29	// | 6 | 2 | 25 |
30	// | 7 | 6 | 31 |
31	//
32	// ## Range queries
33	//
34	// | call | meaning | result |
35	// | --- | --- | --- |
36	// | `Range(2, 5)` | slots 2, 3, 4 | 10 |
37	// | `Range(0, 8)` | everything | 31 |
38	// | `Range(5, 5)` | empty | 0 |
39	// | `Range(-9, 99)` | clamped to the ends | 31 |
40	//
41	// Reads clamp instead of panicking. A realm cannot be redeployed on the same path, so a `Render` that panics on an out-of-range index is a page that is broken for good. Writes do panic: a bad `Add` is a transaction, and aborting it is the useful answer.
42	//
43	// ## What the tree actually stores
44	//
45	// The array is not a copy of the values. Each internal slot holds the sum of a run of them, and the run lengths are the powers of two in the index. That is the whole trick, and `Covers` makes it visible.
46	//
47	// | node | covers slots | sum |
48	// | --- | --- | --- |
49	// | 1 | `[0, 1)` | 3 |
50	// | 2 | `[0, 2)` | 4 |
51	// | 3 | `[2, 3)` | 4 |
52	// | 4 | `[0, 4)` | 9 |
53	// | 5 | `[4, 5)` | 5 |
54	// | 6 | `[4, 6)` | 14 |
55	// | 7 | `[6, 7)` | 2 |
56	// | 8 | `[0, 8)` | 31 |
57	//
58	// A prefix walk visits one node per set bit of the index, and those nodes tile the prefix exactly: no gap, no overlap. Eight slots means at most three nodes per query.
59	//
60	// ## The weighted draw
61	//
62	// `SearchPrefix(target)` names the slot that owns a target drawn below `Total`, in `O(log n)`. Each holder is picked in proportion to their stake, and a zero stake can never be picked at all.
63	//
64	// | holder | stake | owns targets | share |
65	// | --- | --- | --- | --- |
66	// | alice | 30 | `[0, 30)` | 30% |
67	// | bob | 0 | none | 0% |
68	// | carol | 45 | `[30, 75)` | 45% |
69	// | dave | 5 | `[75, 80)` | 5% |
70	// | erin | 20 | `[80, 100)` | 20% |
71	//
72	// | target | SearchPrefix | holder |
73	// | --- | --- | --- |
74	// | 0 | 0 | alice |
75	// | 29 | 0 | alice |
76	// | 30 | 2 | carol |
77	// | 74 | 2 | carol |
78	// | 99 | 4 | erin |
79	//
80	// Note target `30`: it is the first one past alice's share, and it skips bob entirely rather than landing on a holder with nothing staked. The search steps over zero-weight slots because their prefix does not advance, not because anything checks for them.
81	//
82	// ## Why not a plain slice
83	//
84	// Two obvious implementations each win one column and lose another. A realm whose scoreboard is written by every player and read by every page view pays both costs, which is where the middle row earns its keep.
85	//
86	// | structure | point update | prefix sum | weighted draw |
87	// | --- | --- | --- | --- |
88	// | plain slice | `O(1)` | `O(n)` | `O(n)` |
89	// | **Fenwick tree** | `O(log n)` | `O(log n)` | `O(log n)` |
90	// | running totals | `O(n)` | `O(1)` | `O(log n)` |
91	//
92	// The tree also carries no storage overhead: it is exactly `n` values, rearranged.
93}