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.

addrset.gno

3.04 Kb · 80 lines
 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/nym-moultest123/addrset/v0] (which is backed
 4// by an AVL tree): a bump to v1 because the backing data structure — and thus
 5// the on-chain storage layout — changed. The exported API is the same as v0
 6// (Add/Remove/Has/Size/IterateByOffset/ReverseIterateByOffset) EXCEPT that the
 7// v0 `Tree() avl.ITree` escape hatch is intentionally removed, so the backing
 8// store never leaks across realms.
 9//
10// A B+ tree packs many entries per persisted node, so a stored address costs
11// roughly ~0.9 KB vs the AVL backing's ~2.0 KB (and inserts spend materially
12// 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 tree
20//     nodes while their roots and sizes diverge (v0's copies were independent
21//     snapshots).
22//
23// Example:
24//
25//	var set addrset.Set // the zero value is an empty, usable set
26//
27//	set.Add(addr)    // true (newly added)
28//	set.Has(addr)    // true
29//	set.Remove(addr) // true (was present)
30package addrset
31
32import "gno.land/p/nt/bptree/v0"
33
34// Set stores a set of addresses in sorted order. The zero value is an empty,
35// usable set.
36type Set struct {
37	tree bptree.BPTree
38}
39
40// 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}
45
46// 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 removed
51}
52
53// Has checks if an address exists in the set.
54func (s *Set) Has(addr address) bool {
55	return s.tree.Has(string(addr))
56}
57
58// Size returns the number of addresses in the set.
59func (s *Set) Size() int {
60	return s.tree.Size()
61}
62
63// IterateByOffset walks through addresses in sorted order, starting at the
64// given offset and visiting up to count addresses. The callback returns true
65// 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}
71
72// ReverseIterateByOffset walks through addresses in reverse (descending) order,
73// starting at the given offset (counted from the end) and visiting up to count
74// addresses. The callback returns true to stop iteration. The set must not be
75// 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}