1// Package addrset provides a set of blockchain addresses, backed by a B+ tree.2//3// It is the B+ tree successor to [gno.land/p/moul/addrset/v0] (which is backed4// by an AVL tree): a bump to v1 because the backing data structure — and thus5// the on-chain storage layout — changed. The exported API is the same as v06// (Add/Remove/Has/Size/IterateByOffset/ReverseIterateByOffset) EXCEPT that the7// v0 `Tree() avl.ITree` escape hatch is intentionally removed, so the backing8// store never leaks across realms.9//10// A B+ tree packs many entries per persisted node, so a stored address costs11// roughly ~0.9 KB vs the AVL backing's ~2.0 KB (and inserts spend materially12// less gas). Prefer v1 when the set is part of persisted realm state.13//14// Two behavioral differences from v0, both consequences of the in-place-15// mutating B+ tree backing:16//17// - do NOT mutate the set (Add/Remove) from inside an iteration callback —18// the AVL backing's copy-on-write tolerated it, this one does not;19// - do NOT copy a non-zero Set by value — the copies would share live tree20// nodes while their roots and sizes diverge (v0's copies were independent21// snapshots).22//23// Example:24//25// var set addrset.Set // the zero value is an empty, usable set26//27// set.Add(addr) // true (newly added)28// set.Has(addr) // true29// set.Remove(addr) // true (was present)30package addrset3132import "gno.land/p/nt/bptree/v0"3334// Set stores a set of addresses in sorted order. The zero value is an empty,35// usable set.36type Set struct {37 tree bptree.BPTree38}3940// Add inserts an address into the set.41// Returns true if the address was newly added, false if it already existed.42func (s *Set) Add(addr address) bool {43 return !s.tree.Set(string(addr), nil)44}4546// Remove deletes an address from the set.47// Returns true if the address was found and removed, false if it didn't exist.48func (s *Set) Remove(addr address) bool {49 _, removed := s.tree.Remove(string(addr))50 return removed51}5253// Has checks if an address exists in the set.54func (s *Set) Has(addr address) bool {55 return s.tree.Has(string(addr))56}5758// Size returns the number of addresses in the set.59func (s *Set) Size() int {60 return s.tree.Size()61}6263// IterateByOffset walks through addresses in sorted order, starting at the64// given offset and visiting up to count addresses. The callback returns true65// to stop iteration. The set must not be modified during iteration.66func (s *Set) IterateByOffset(offset int, count int, cb func(addr address) bool) {67 s.tree.IterateByOffset(offset, count, func(key string, _ any) bool {68 return cb(address(key))69 })70}7172// ReverseIterateByOffset walks through addresses in reverse (descending) order,73// starting at the given offset (counted from the end) and visiting up to count74// addresses. The callback returns true to stop iteration. The set must not be75// modified during iteration.76func (s *Set) ReverseIterateByOffset(offset int, count int, cb func(addr address) bool) {77 s.tree.ReverseIterateByOffset(offset, count, func(key string, _ any) bool {78 return cb(address(key))79 })80}81Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.