Search Apps Documentation Source Content File Folder Download Copy Actions Download

tree.gno

2.98 Kb ยท 124 lines
  1package staker
  2
  3import (
  4	"strconv"
  5	"strings"
  6
  7	"gno.land/p/nt/avl"
  8	"gno.land/p/nt/ufmt"
  9)
 10
 11// UintTree is a wrapper around an AVL tree for storing block timestamps as strings.
 12// Since block timestamps are defined as int64, we take int64 and convert it to uint64 for the tree.
 13//
 14// Methods:
 15// - Get: Retrieves a value associated with a uint64 key.
 16// - set: Stores a value with a uint64 key.
 17// - Has: Checks if a uint64 key exists in the tree.
 18// - remove: Removes a uint64 key and its associated value.
 19// - Iterate: Iterates over keys and values in a range.
 20// - ReverseIterate: Iterates in reverse order over keys and values in a range.
 21type UintTree struct {
 22	tree *avl.Tree // blockTimestamp -> any
 23}
 24
 25// NewUintTree creates a new UintTree instance.
 26func NewUintTree() *UintTree {
 27	return &UintTree{
 28		tree: avl.NewTree(),
 29	}
 30}
 31
 32func (self *UintTree) Get(key int64) (any, bool) {
 33	v, ok := self.tree.Get(EncodeInt64(key))
 34	if !ok {
 35		return nil, false
 36	}
 37	return v, true
 38}
 39
 40func (self *UintTree) Set(key int64, value any) {
 41	self.tree.Set(EncodeInt64(key), value)
 42}
 43
 44func (self *UintTree) Has(key int64) bool {
 45	return self.tree.Has(EncodeInt64(key))
 46}
 47
 48func (self *UintTree) Remove(key int64) {
 49	self.tree.Remove(EncodeInt64(key))
 50}
 51
 52func (self *UintTree) Iterate(start, end int64, fn func(key int64, value any) bool) {
 53	self.tree.Iterate(EncodeInt64(start), EncodeInt64(end), func(key string, value any) bool {
 54		return fn(DecodeInt64(key), value)
 55	})
 56}
 57
 58func (self *UintTree) ReverseIterate(start, end int64, fn func(key int64, value any) bool) {
 59	self.tree.ReverseIterate(EncodeInt64(start), EncodeInt64(end), func(key string, value any) bool {
 60		return fn(DecodeInt64(key), value)
 61	})
 62}
 63
 64// Size returns the number of entries in the tree.
 65func (self *UintTree) Size() int {
 66	return self.tree.Size()
 67}
 68
 69// EncodeUint converts a uint64 number into a zero-padded 20-character string.
 70//
 71// Parameters:
 72// - num (uint64): The number to encode.
 73//
 74// Returns:
 75// - string: A zero-padded string representation of the number.
 76//
 77// Example:
 78// Input: 12345
 79// Output: "00000000000000012345"
 80func EncodeUint(num uint64) string {
 81	// Convert the value to a decimal string.
 82	s := strconv.FormatUint(num, 10)
 83
 84	// Zero-pad to a total length of 20 characters.
 85	zerosNeeded := 20 - len(s)
 86	return strings.Repeat("0", zerosNeeded) + s
 87}
 88
 89func EncodeInt64(num int64) string {
 90	if num < 0 {
 91		panic(ufmt.Sprintf("negative value not supported: %d", num))
 92	}
 93	return EncodeUint(uint64(num))
 94}
 95
 96// DecodeUint converts a zero-padded string back into a uint64 number.
 97//
 98// Parameters:
 99// - s (string): The zero-padded string.
100//
101// Returns:
102// - uint64: The decoded number.
103//
104// Panics:
105// - If the string cannot be parsed into a uint64.
106//
107// Example:
108// Input: "00000000000000012345"
109// Output: 12345
110func DecodeUint(s string) uint64 {
111	num, err := strconv.ParseUint(s, 10, 64)
112	if err != nil {
113		panic(err)
114	}
115	return num
116}
117
118func DecodeInt64(s string) int64 {
119	num, err := strconv.ParseInt(s, 10, 64)
120	if err != nil {
121		panic(err)
122	}
123	return num
124}