Transaction

C52B3A0A2A9DBA…49214BE2FFF1

Block 25,936 · index 0 · indexed

Summary

Hash
C52B3A0A2A9DBAB9BB7CC15076D1716E68BF9D3F8765C9C06B2A49214BE2FFF1
Block
25,936
Size
6236 bytes
Gas used
10,827,790 / 12,993,408
Fee
1000000ugnot
Memo
gnopublish
Status
success

Messages

#1AddPackagegno.land/p/moul/x/daily/heap/v09 arguments

Arguments · 9

  1. #1heap
  2. #2README.md
  3. #3# `gno.land/p/moul/x/daily/heap/v0` **Binary heap / priority queue** — `New`, `NewMax`, `Push`, `Pop`, `Peek`, `Drain`, `Clone`, `Len`, `IsEmpty`, `IsMax`, `MaxItems`. ```go import "gno.land/p/moul/x/daily/heap/v0" h := heap.New() // min-heap; NewMax() for max h.Push("pay invoice", 1) h.Push("clear cache", 9) h.Peek() // "pay invoice", 1, true — does not remove h.Drain() // ["pay invoice" "clear cache"] ``` Go's `container/heap` makes you implement five methods and hands back an interface. This is the concrete structure instead: an implicit binary heap in a slice, `Push`/`Pop` in O(log n), `Peek` in O(1). **The ordering is total.** Equal priorities pop **oldest-first**, and that tiebreak does *not* invert in a max-heap — only the priority comparison does. Without it, ties would fall back on whatever order the backing slice happened to hold, and two nodes could pop the same queue differently: a consensus bug, not a cosmetic one. `MaxItems` (4096) bounds growth; a full heap refuses new items rather than growing without limit. **Live demo:** [`r/moul/x/daily/heapdemo`](https://github.com/moul/gno-contracts/tree/main/r/moul/x/daily/heapdemo/v0) · render it at [`/r/moul/x/daily/heapdemo/v0`](https://gno.land/r/moul/x/daily/heapdemo/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 -->
  4. #4gnomod.toml
  5. #5module = "gno.land/p/moul/x/daily/heap/v0" gno = "0.9"
  6. #6heap.gno
  7. #7// Package heap is a binary min-heap / priority queue over string items with // integer priorities, as a pure, reusable package. // // Go's container/heap makes the caller implement five methods and hands back an // interface; that indirection buys generality this chain does not need and // costs gas it does. This is the concrete data structure instead: an implicit // binary heap in a slice, Push/Pop in O(log n), Peek in O(1). // // Ordering is TOTAL and deterministic. Equal priorities are broken by insertion // sequence, so two heaps fed the same items in the same order always pop the // same sequence — a heap that reordered ties by allocation address would make a // Render vary between nodes, which is a consensus bug rather than a cosmetic // one. // // A live demo of this package is at // [r/moul/x/daily/heapdemo](/r/moul/x/daily/heapdemo/v0). package heap // MaxItems bounds the heap so gas stays predictable. const MaxItems = 4096 type item struct { value string priority int seq int // insertion sequence, breaks priority ties } // Heap is a binary min-heap: the lowest priority pops first. type Heap struct { items []item next int // monotonic insertion counter max bool } // New returns an empty min-heap (lowest priority pops first). func New() *Heap { return &Heap{} } // NewMax returns an empty max-heap (highest priority pops first). Ties are // still broken by insertion order, oldest first. func NewMax() *Heap { return &Heap{max: true} } // Len returns the number of items. func (h *Heap) Len() int { return len(h.items) } // IsEmpty reports whether the heap holds nothing. func (h *Heap) IsEmpty() bool { return len(h.items) == 0 } // IsMax reports whether this is a max-heap. func (h *Heap) IsMax() bool { return h.max } // less reports whether a should pop before b. func (h *Heap) less(a, b item) bool { if a.priority != b.priority { if h.max { return a.priority > b.priority } return a.priority < b.priority } // Total order: equal priorities pop oldest-first, in BOTH heap kinds. return a.seq < b.seq } // Push adds value with the given priority. Returns false when the heap is full. func (h *Heap) Push(value string, priority int) bool { if len(h.items) >= MaxItems { return false } h.items = append(h.items, item{value: value, priority: priority, seq: h.next}) h.next++ h.up(len(h.items) - 1) return true } // Peek returns the item that would pop next, without removing it. func (h *Heap) Peek() (value string, priority int, ok bool) { if len(h.items) == 0 { return "", 0, false } return h.items[0].value, h.items[0].priority, true } // Pop removes and returns the next item. func (h *Heap) Pop() (value string, priority int, ok bool) { if len(h.items) == 0 { return "", 0, false } top := h.items[0] last := len(h.items) - 1 h.items[0] = h.items[last] h.items = h.items[:last] if len(h.items) > 0 { h.down(0) } return top.value, top.priority, true } // Drain pops everything, returning values in pop order. The heap ends empty. func (h *Heap) Drain() []string { out := make([]string, 0, len(h.items)) for { v, _, ok := h.Pop() if !ok { return out } out = append(out, v) } } // Clone returns an independent copy. func (h *Heap) Clone() *Heap { cp := &Heap{items: make([]item, len(h.items)), next: h.next, max: h.max} copy(cp.items, h.items) return cp } func (h *Heap) up(i int) { for i > 0 { parent := (i - 1) / 2 if !h.less(h.items[i], h.items[parent]) { return } h.items[i], h.items[parent] = h.items[parent], h.items[i] i = parent } } func (h *Heap) down(i int) { n := len(h.items) for { left := 2*i + 1 if left >= n { return } best := left if right := left + 1; right < n && h.less(h.items[right], h.items[left]) { best = right } if !h.less(h.items[best], h.items[i]) { return } h.items[i], h.items[best] = h.items[best], h.items[i] i = best } }
  8. #8/gno.MemPackageType
  9. #9 MPUserProd

Result log

msg:0,success:true,log:,events:[]

← Back to block 25,936