diff --git a/agent/pkg/agent/agent_pool.go b/agent/pkg/agent/agent_pool.go index 49c3e6cd..58c61eb0 100644 --- a/agent/pkg/agent/agent_pool.go +++ b/agent/pkg/agent/agent_pool.go @@ -1,11 +1,12 @@ package agent import ( + + "github.com/puzpuzpuz/xsync/v4" "github.com/yusing/go-proxy/internal/common" - "github.com/yusing/go-proxy/internal/utils/functional" ) -var agentPool = functional.NewMapOf[string, *AgentConfig]() +var agentPool = xsync.NewMap[string, *AgentConfig](xsync.WithPresize(10)) func init() { if common.IsTest { diff --git a/internal/serialization/serialization.go b/internal/serialization/serialization.go index e1c10b9c..4efe4e7f 100644 --- a/internal/serialization/serialization.go +++ b/internal/serialization/serialization.go @@ -15,7 +15,6 @@ import ( "github.com/puzpuzpuz/xsync/v4" "github.com/yusing/go-proxy/internal/gperr" "github.com/yusing/go-proxy/internal/utils" - "github.com/yusing/go-proxy/internal/utils/functional" "github.com/yusing/go-proxy/internal/utils/strutils" ) @@ -565,7 +564,7 @@ func UnmarshalValidateYAMLIntercept[T any](data []byte, target *T, intercept fun return MapUnmarshalValidate(m, target) } -func UnmarshalValidateYAMLXSync[V any](data []byte) (_ functional.Map[string, V], err gperr.Error) { +func UnmarshalValidateYAMLXSync[V any](data []byte) (_ *xsync.Map[string, V], err gperr.Error) { data, err = substituteEnv(data) if err != nil { return @@ -579,7 +578,11 @@ func UnmarshalValidateYAMLXSync[V any](data []byte) (_ functional.Map[string, V] if err = MapUnmarshalValidate(m, m2); err != nil { return } - return functional.NewMapFrom(m2), nil + ret := xsync.NewMap[string, V](xsync.WithPresize(len(m))) + for k, v := range m2 { + ret.Store(k, v) + } + return ret, nil } func loadSerialized[T any](path string, dst *T, deserialize func(data []byte, dst any) error) error { diff --git a/internal/utils/functional/map.go b/internal/utils/functional/map.go deleted file mode 100644 index bbc355a6..00000000 --- a/internal/utils/functional/map.go +++ /dev/null @@ -1,103 +0,0 @@ -package functional - -import ( - "sync" - - "github.com/goccy/go-yaml" - "github.com/puzpuzpuz/xsync/v4" -) - -type Map[KT comparable, VT any] struct { - *xsync.Map[KT, VT] -} - -const minParallelSize = 4 - -func NewMapOf[KT comparable, VT any](options ...func(*xsync.MapConfig)) Map[KT, VT] { - return Map[KT, VT]{xsync.NewMap[KT, VT](options...)} -} - -func NewMapFrom[KT comparable, VT any](m map[KT]VT) (res Map[KT, VT]) { - res = NewMapOf[KT, VT](xsync.WithPresize(len(m))) - for k, v := range m { - res.Store(k, v) - } - return -} - -func NewMap[MapType Map[KT, VT], KT comparable, VT any]() Map[KT, VT] { - return NewMapOf[KT, VT]() -} - -// RangeAll calls the given function for each key-value pair in the map. -// -// Parameters: -// -// do: function to call for each key-value pair -// -// Returns: -// -// nothing -func (m Map[KT, VT]) RangeAll(do func(k KT, v VT)) { - m.Range(func(k KT, v VT) bool { - do(k, v) - return true - }) -} - -// RangeAllParallel calls the given function for each key-value pair in the map, -// in parallel. The map is not safe for modification from within the function. -// -// Parameters: -// -// do: function to call for each key-value pair -// -// Returns: -// -// nothing -func (m Map[KT, VT]) RangeAllParallel(do func(k KT, v VT)) { - if m.Size() < minParallelSize { - m.RangeAll(do) - return - } - - var wg sync.WaitGroup - for k, v := range m.Range { - wg.Add(1) - go func(k KT, v VT) { - defer wg.Done() - do(k, v) - }(k, v) - } - wg.Wait() -} - -// CollectErrors calls the given function for each key-value pair in the map, -// then returns a slice of errors collected. -func (m Map[KT, VT]) CollectErrors(do func(k KT, v VT) error) []error { - errs := make([]error, 0) - m.Range(func(k KT, v VT) bool { - if err := do(k, v); err != nil { - errs = append(errs, err) - } - return true - }) - return errs -} - -func (m Map[KT, VT]) Has(k KT) bool { - _, ok := m.Load(k) - return ok -} - -func (m Map[KT, VT]) String() string { - tmp := make(map[KT]VT, m.Size()) - m.RangeAll(func(k KT, v VT) { - tmp[k] = v - }) - data, err := yaml.Marshal(&tmp) - if err != nil { - return err.Error() - } - return string(data) -} diff --git a/internal/utils/functional/map_test.go b/internal/utils/functional/map_test.go deleted file mode 100644 index 97152101..00000000 --- a/internal/utils/functional/map_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package functional_test - -import ( - "testing" - - . "github.com/yusing/go-proxy/internal/utils/functional" - . "github.com/yusing/go-proxy/internal/utils/testing" -) - -func TestNewMapFrom(t *testing.T) { - m := NewMapFrom(map[string]int{ - "a": 1, - "b": 2, - "c": 3, - }) - ExpectEqual(t, m.Size(), 3) - ExpectTrue(t, m.Has("a")) - ExpectTrue(t, m.Has("b")) - ExpectTrue(t, m.Has("c")) -} diff --git a/internal/watcher/health/monitor/last_seen.go b/internal/watcher/health/monitor/last_seen.go index 36e7cebc..f7c80be6 100644 --- a/internal/watcher/health/monitor/last_seen.go +++ b/internal/watcher/health/monitor/last_seen.go @@ -3,10 +3,10 @@ package monitor import ( "time" - F "github.com/yusing/go-proxy/internal/utils/functional" + "github.com/puzpuzpuz/xsync/v4" ) -var lastSeenMap = F.NewMapOf[string, time.Time]() +var lastSeenMap = xsync.NewMap[string, time.Time](xsync.WithPresize(50), xsync.WithGrowOnly()) func SetLastSeen(service string, lastSeen time.Time) { lastSeenMap.Store(service, lastSeen)