PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/daily/fenwick/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / x / daily / fenwick
Files
4 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/daily/fenwick/v0
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • fenwick.gnogno
  • fenwick_test.gnogno
README.mdPreviewRaw
# `gno.land/p/moul/x/daily/fenwick/v0`

**A Binary Indexed Tree over `int64`**: `New`, `FromSlice`, `Add`, `Set`, `Prefix`, `Range`, `At`, `Total`, `SearchPrefix`, `Slice`, `Covers`.

```go
import "gno.land/p/moul/x/daily/fenwick/v0"

tr := fenwick.FromSlice([]int64{3, 1, 4, 1, 5})
tr.Prefix(3)          // 8    sum of [0, 3)
tr.Range(1, 4)        // 6    sum of [1, 4)
tr.Add(2, 10)         //      point update, O(log n)
tr.SearchPrefix(7)    // 2    the slot owning target 7
```

A realm that keeps a running tally is choosing between two bad options without
noticing. A plain slice updates in `O(1)` and sums in `O(n)`. A slice of running
totals sums in `O(1)` and updates in `O(n)`. A scoreboard is written by every
player *and* read by every page view, so it pays both costs. A Fenwick tree does
both in `O(log n)`, in exactly `n` values of storage, rearranged.

**The operation worth importing a package for is `SearchPrefix`**, not the prefix
sums. Given a target below `Total` it names the slot that owns it, in `O(log n)`,
by descending the tree rather than scanning it. That is the primitive behind a
stake-weighted draw (pick a number, ask who holds it) and behind a leaderboard's
rank lookup. Prefix sums alone would not justify a data structure.

Three behaviours worth knowing before you use it:

- **Reads are total, writes panic**, and the asymmetry is deliberate. `Prefix`,
  `Range`, `At`, `Covers` and `SearchPrefix` clamp whatever index they are
  handed; `Add`, `Set` and `New` panic. A read is what `Render` calls, and 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 permanently. A write is a
  transaction, where aborting is the useful answer and the caller can still
  recover.
- **A zero-weight slot is never selected by `SearchPrefix`.** It falls out of the
  descent rather than being checked for: a zero does not advance the prefix, so
  no target can land on it. That is the property a weighted draw depends on, and
  the one a naive "first running total `>=` target" scan gets wrong.
- **`SearchPrefix` is only meaningful when every value is non-negative.** With a
  negative in the tree the prefix sums stop increasing and "the smallest index
  whose prefix exceeds the target" stops being well defined. Negative values are
  not forbidden, because `Add` with a negative delta is the ordinary way to
  decrement a counter; it is this one method that needs them absent.

`MaxSize` caps construction at 65,536 slots. Queries are `O(log n)` whatever the
size; the cap is there so the single `O(n)` operation, building the tree, cannot
be sized from unbounded user input. Sums must fit in `int64`, which gno does not
check and neither does this package.

`Covers(i)` reports which slots an internal node summarizes. It is not needed to
use the tree; it exists so the structure can be shown rather than asserted, and
the demo realm renders it.

Live demo: [`r/moul/x/daily/fenwickdemo`](/r/moul/x/daily/fenwickdemo/v0).

<!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) -->

---

Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

> 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md).

<!-- END GNOCONTRACTS FOOTER -->

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.