From f80474aedfe44680ddfd3b2eaf1e52e5909f1309 Mon Sep 17 00:00:00 2001 From: Zach Kelling Date: Wed, 4 Feb 2026 15:43:42 -0800 Subject: [PATCH] chore: sync dependencies and format code --- averager_heap.go | 45 +++++----- averager_heap_test.go | 4 +- go.mod | 4 +- go.sum | 8 +- safe/go.mod | 2 +- safe/go.sum | 2 +- set/set.go | 194 +++++++++++++++++++++--------------------- 7 files changed, 128 insertions(+), 131 deletions(-) diff --git a/averager_heap.go b/averager_heap.go index 0643143..587ddeb 100644 --- a/averager_heap.go +++ b/averager_heap.go @@ -4,62 +4,59 @@ package math import ( - "github.com/luxfi/ids" "github.com/luxfi/math/heap" ) -var _ AveragerHeap = (*averagerHeap)(nil) - -// TODO replace this interface with utils/heap -// AveragerHeap maintains a heap of the averagers. -type AveragerHeap interface { - // Add the average to the heap. If [nodeID] is already in the heap, the +// AveragerHeap maintains a heap of the averagers keyed by a comparable type. +// K is the key type (e.g., ids.NodeID). +type AveragerHeap[K comparable] interface { + // Add the average to the heap. If key is already in the heap, the // average will be replaced and the old average will be returned. If there // was not an old average, false will be returned. - Add(nodeID ids.NodeID, averager Averager) (Averager, bool) + Add(key K, averager Averager) (Averager, bool) // Remove attempts to remove the average that was added with the provided - // [nodeID], if none is contained in the heap, [false] will be returned. - Remove(nodeID ids.NodeID) (Averager, bool) + // key, if none is contained in the heap, [false] will be returned. + Remove(key K) (Averager, bool) // Pop attempts to remove the node with either the largest or smallest // average, depending on if this is a max heap or a min heap, respectively. - Pop() (ids.NodeID, Averager, bool) + Pop() (K, Averager, bool) // Peek attempts to return the node with either the largest or smallest // average, depending on if this is a max heap or a min heap, respectively. - Peek() (ids.NodeID, Averager, bool) + Peek() (K, Averager, bool) // Len returns the number of nodes that are currently in the heap. Len() int } -type averagerHeap struct { - heap heap.Map[ids.NodeID, Averager] +type averagerHeap[K comparable] struct { + heap heap.Map[K, Averager] } // NewMaxAveragerHeap returns a new empty max heap. The returned heap is not // thread safe. -func NewMaxAveragerHeap() AveragerHeap { - return averagerHeap{ - heap: heap.NewMap[ids.NodeID, Averager](func(a, b Averager) bool { +func NewMaxAveragerHeap[K comparable]() AveragerHeap[K] { + return averagerHeap[K]{ + heap: heap.NewMap[K, Averager](func(a, b Averager) bool { return a.Read() > b.Read() }), } } -func (h averagerHeap) Add(nodeID ids.NodeID, averager Averager) (Averager, bool) { - return h.heap.Push(nodeID, averager) +func (h averagerHeap[K]) Add(key K, averager Averager) (Averager, bool) { + return h.heap.Push(key, averager) } -func (h averagerHeap) Remove(nodeID ids.NodeID) (Averager, bool) { - return h.heap.Remove(nodeID) +func (h averagerHeap[K]) Remove(key K) (Averager, bool) { + return h.heap.Remove(key) } -func (h averagerHeap) Pop() (ids.NodeID, Averager, bool) { +func (h averagerHeap[K]) Pop() (K, Averager, bool) { return h.heap.Pop() } -func (h averagerHeap) Peek() (ids.NodeID, Averager, bool) { +func (h averagerHeap[K]) Peek() (K, Averager, bool) { return h.heap.Peek() } -func (h averagerHeap) Len() int { +func (h averagerHeap[K]) Len() int { return h.heap.Len() } diff --git a/averager_heap_test.go b/averager_heap_test.go index dca4351..52ea009 100644 --- a/averager_heap_test.go +++ b/averager_heap_test.go @@ -19,12 +19,12 @@ func TestAveragerHeap(t *testing.T) { tests := []struct { name string - h AveragerHeap + h AveragerHeap[ids.NodeID] a []Averager }{ { name: "max heap", - h: NewMaxAveragerHeap(), + h: NewMaxAveragerHeap[ids.NodeID](), a: []Averager{ NewAverager(0, time.Second, time.Now()), NewAverager(-1, time.Second, time.Now()), diff --git a/go.mod b/go.mod index cef477d..a9063a5 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/luxfi/math/big v0.1.0 github.com/luxfi/sampler v1.0.0 github.com/stretchr/testify v1.11.1 - golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 + golang.org/x/exp v0.0.0-20260112195511-716be5621a96 ) require ( @@ -16,7 +16,7 @@ require ( github.com/luxfi/crypto v1.17.36 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - golang.org/x/crypto v0.46.0 // indirect + golang.org/x/crypto v0.47.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index a102155..4fd0e31 100644 --- a/go.sum +++ b/go.sum @@ -26,10 +26,10 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= -golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/safe/go.mod b/safe/go.mod index c8aa8e3..648773b 100644 --- a/safe/go.mod +++ b/safe/go.mod @@ -2,4 +2,4 @@ module github.com/luxfi/math/safe go 1.24.9 -require golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 +require golang.org/x/exp v0.0.0-20260112195511-716be5621a96 diff --git a/safe/go.sum b/safe/go.sum index d140290..d66ce26 100644 --- a/safe/go.sum +++ b/safe/go.sum @@ -1 +1 @@ -golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= diff --git a/set/set.go b/set/set.go index a508d47..bc71ee2 100644 --- a/set/set.go +++ b/set/set.go @@ -1,8 +1,8 @@ package set import ( - "encoding/json" - "sort" + "encoding/json" + "sort" ) // Set represents a set of unique elements @@ -10,170 +10,170 @@ type Set[T comparable] map[T]struct{} // Of creates a new set with the given elements func Of[T comparable](elements ...T) Set[T] { - s := make(Set[T], len(elements)) - for _, e := range elements { - s[e] = struct{}{} - } - return s + s := make(Set[T], len(elements)) + for _, e := range elements { + s[e] = struct{}{} + } + return s } // Add adds one or more elements to the set // If the set is nil, this method will panic. Use NewSet() or Of() to create an initialized set. func (s Set[T]) Add(elements ...T) { - if s == nil { - panic("set: Add called on nil Set - use NewSet() or Of() to create an initialized set") - } - for _, element := range elements { - s[element] = struct{}{} - } + if s == nil { + panic("set: Add called on nil Set - use NewSet() or Of() to create an initialized set") + } + for _, element := range elements { + s[element] = struct{}{} + } } // Contains checks if an element is in the set func (s Set[T]) Contains(element T) bool { - _, exists := s[element] - return exists + _, exists := s[element] + return exists } // Remove removes an element from the set func (s Set[T]) Remove(element T) { - delete(s, element) + delete(s, element) } // Len returns the number of elements in the set func (s Set[T]) Len() int { - return len(s) + return len(s) } // List returns a slice of all elements in the set func (s Set[T]) List() []T { - result := make([]T, 0, len(s)) - for element := range s { - result = append(result, element) - } - return result + result := make([]T, 0, len(s)) + for element := range s { + result = append(result, element) + } + return result } // Clear removes all elements from the set func (s Set[T]) Clear() { - for k := range s { - delete(s, k) - } + for k := range s { + delete(s, k) + } } // Union returns a new set containing all elements from both sets func (s Set[T]) Union(other Set[T]) Set[T] { - result := make(Set[T]) - for k := range s { - result[k] = struct{}{} - } - for k := range other { - result[k] = struct{}{} - } - return result + result := make(Set[T]) + for k := range s { + result[k] = struct{}{} + } + for k := range other { + result[k] = struct{}{} + } + return result } // Intersection returns a new set containing only elements in both sets func (s Set[T]) Intersection(other Set[T]) Set[T] { - result := make(Set[T]) - for k := range s { - if other.Contains(k) { - result[k] = struct{}{} - } - } - return result + result := make(Set[T]) + for k := range s { + if other.Contains(k) { + result[k] = struct{}{} + } + } + return result } // Difference returns a new set containing elements in s but not in other func (s Set[T]) Difference(other Set[T]) Set[T] { - result := make(Set[T]) - for k := range s { - if !other.Contains(k) { - result[k] = struct{}{} - } - } - return result + result := make(Set[T]) + for k := range s { + if !other.Contains(k) { + result[k] = struct{}{} + } + } + return result } // Equals checks if two sets contain the same elements func (s Set[T]) Equals(other Set[T]) bool { - if len(s) != len(other) { - return false - } - for k := range s { - if !other.Contains(k) { - return false - } - } - return true + if len(s) != len(other) { + return false + } + for k := range s { + if !other.Contains(k) { + return false + } + } + return true } // Overlaps checks if two sets have any common elements func (s Set[T]) Overlaps(other Set[T]) bool { - for k := range s { - if other.Contains(k) { - return true - } - } - return false + for k := range s { + if other.Contains(k) { + return true + } + } + return false } // Pop removes and returns an arbitrary element from the set // Returns the element and true if the set was non-empty, otherwise returns zero value and false func (s Set[T]) Pop() (T, bool) { - for k := range s { - delete(s, k) - return k, true - } - var zero T - return zero, false + for k := range s { + delete(s, k) + return k, true + } + var zero T + return zero, false } // NewSet creates a new empty set with optional initial capacity func NewSet[T comparable](capacity ...int) Set[T] { - if len(capacity) > 0 && capacity[0] > 0 { - return make(Set[T], capacity[0]) - } - return make(Set[T]) + if len(capacity) > 0 && capacity[0] > 0 { + return make(Set[T], capacity[0]) + } + return make(Set[T]) } // MarshalJSON implements json.Marshaler interface // Marshals the set as a JSON array of elements in sorted order func (s Set[T]) MarshalJSON() ([]byte, error) { - // Convert set to slice for marshaling - list := s.List() + // Convert set to slice for marshaling + list := s.List() - // Sort for consistent output (best effort for common types) - if len(list) > 1 { - switch any(list).(type) { - case []int: - sort.Ints(any(list).([]int)) - case []string: - sort.Strings(any(list).([]string)) - case []float64: - sort.Float64s(any(list).([]float64)) - } - } + // Sort for consistent output (best effort for common types) + if len(list) > 1 { + switch any(list).(type) { + case []int: + sort.Ints(any(list).([]int)) + case []string: + sort.Strings(any(list).([]string)) + case []float64: + sort.Float64s(any(list).([]float64)) + } + } - return json.Marshal(list) + return json.Marshal(list) } // UnmarshalJSON implements json.Unmarshaler interface // Unmarshals a JSON array into a set, replacing existing contents func (s *Set[T]) UnmarshalJSON(data []byte) error { - var list []T - if err := json.Unmarshal(data, &list); err != nil { - return err - } + var list []T + if err := json.Unmarshal(data, &list); err != nil { + return err + } - // Create a new set to replace existing contents - *s = make(Set[T], len(list)) + // Create a new set to replace existing contents + *s = make(Set[T], len(list)) - // Add all elements from the list - for _, element := range list { - (*s)[element] = struct{}{} - } + // Add all elements from the list + for _, element := range list { + (*s)[element] = struct{}{} + } - return nil + return nil } // Peek returns a random element from the set.