addrset.gno
2.98 Kb ยท 100 lines
1// Package addrset provides a specialized set data structure for managing unique Gno addresses.
2//
3// It is built on top of an AVL tree for efficient operations and maintains addresses in sorted order.
4// This package is particularly useful when you need to:
5// - Track a collection of unique addresses (e.g., for whitelists, participants, etc.)
6// - Efficiently check address membership
7// - Support pagination when displaying addresses
8//
9// Example usage:
10//
11// import (
12// "std"
13// "gno.land/p/moul/addrset"
14// )
15//
16// func MyHandler() {
17// // Create a new address set
18// var set addrset.Set
19//
20// // Add some addresses
21// addr1 := std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
22// addr2 := std.Address("g1sss5g0rkqr88k4u648yd5d3l9t4d8vvqwszqth")
23//
24// set.Add(addr1) // returns true (newly added)
25// set.Add(addr2) // returns true (newly added)
26// set.Add(addr1) // returns false (already exists)
27//
28// // Check membership
29// if set.Has(addr1) {
30// // addr1 is in the set
31// }
32//
33// // Get size
34// size := set.Size() // returns 2
35//
36// // Iterate with pagination (10 items per page, starting at offset 0)
37// set.IterateByOffset(0, 10, func(addr std.Address) bool {
38// // Process addr
39// return false // continue iteration
40// })
41//
42// // Remove an address
43// set.Remove(addr1) // returns true (was present)
44// set.Remove(addr1) // returns false (not present)
45// }
46package addrset
47
48import (
49 "std"
50
51 "gno.land/p/demo/avl"
52)
53
54type Set struct {
55 tree avl.Tree
56}
57
58// Add inserts an address into the set.
59// Returns true if the address was newly added, false if it already existed.
60func (s *Set) Add(addr std.Address) bool {
61 return !s.tree.Set(string(addr), nil)
62}
63
64// Remove deletes an address from the set.
65// Returns true if the address was found and removed, false if it didn't exist.
66func (s *Set) Remove(addr std.Address) bool {
67 _, removed := s.tree.Remove(string(addr))
68 return removed
69}
70
71// Has checks if an address exists in the set.
72func (s *Set) Has(addr std.Address) bool {
73 return s.tree.Has(string(addr))
74}
75
76// Size returns the number of addresses in the set.
77func (s *Set) Size() int {
78 return s.tree.Size()
79}
80
81// IterateByOffset walks through addresses starting at the given offset.
82// The callback should return true to stop iteration.
83func (s *Set) IterateByOffset(offset int, count int, cb func(addr std.Address) bool) {
84 s.tree.IterateByOffset(offset, count, func(key string, _ any) bool {
85 return cb(std.Address(key))
86 })
87}
88
89// ReverseIterateByOffset walks through addresses in reverse order starting at the given offset.
90// The callback should return true to stop iteration.
91func (s *Set) ReverseIterateByOffset(offset int, count int, cb func(addr std.Address) bool) {
92 s.tree.ReverseIterateByOffset(offset, count, func(key string, _ any) bool {
93 return cb(std.Address(key))
94 })
95}
96
97// Tree returns the underlying AVL tree for advanced usage.
98func (s *Set) Tree() avl.ITree {
99 return &s.tree
100}