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}