package utils import ( "sync" "sync/atomic" ) // MapPool Map对象池 type MapPool[K comparable, V any] struct { pool sync.Pool reused int64 maxSize int // 最大保留大小 } // NewMapPool 创建新的Map池 func NewMapPool[K comparable, V any](initSize, maxSize int) *MapPool[K, V] { if initSize <= 0 { initSize = 16 } if maxSize <= 0 { maxSize = 1024 } return &MapPool[K, V]{ pool: sync.Pool{ New: func() interface{} { m := make(map[K]V, initSize) return &m }, }, maxSize: maxSize, } } // Get 获取Map func (p *MapPool[K, V]) Get() map[K]V { mapPtr := p.pool.Get().(*map[K]V) m := *mapPtr // 清空现有内容 for k := range m { delete(m, k) } atomic.AddInt64(&p.reused, 1) return m } // Put 归还Map func (p *MapPool[K, V]) Put(m map[K]V) { if m == nil { return } // 如果大小超过限制,不放回池中 if len(m) > p.maxSize { return } p.pool.Put(&m) } // GetWithCapacity 获取指定容量的Map func (p *MapPool[K, V]) GetWithCapacity(capacity int) map[K]V { m := p.Get() // 如果当前Map容量估计不足,重新创建 // Go的map没有直接的容量概念,我们使用长度作为估算 if capacity > p.maxSize { p.Put(m) return make(map[K]V, capacity) } return m } // GetReusedCount 获取复用次数 func (p *MapPool[K, V]) GetReusedCount() int64 { return atomic.LoadInt64(&p.reused) } // 预定义的常用类型Map池 var ( StringToStringMapPool = NewMapPool[string, string](16, 512) StringToIntMapPool = NewMapPool[string, int](16, 512) IntToStringMapPool = NewMapPool[int, string](16, 512) StringToStructMapPool = NewMapPool[string, struct{}](16, 512) IntToStructMapPool = NewMapPool[int, struct{}](16, 512) ) // CreateStringSet 创建字符串集合(用于去重) func CreateStringSet(slice []string) map[string]struct{} { m := StringToStructMapPool.GetWithCapacity(len(slice)) for _, item := range slice { m[item] = struct{}{} } return m } // CreateIntSet 创建整数集合(用于去重) func CreateIntSet(slice []int) map[int]struct{} { m := IntToStructMapPool.GetWithCapacity(len(slice)) for _, item := range slice { m[item] = struct{}{} } return m } // ReturnStringSet 归还字符串集合 func ReturnStringSet(m map[string]struct{}) { StringToStructMapPool.Put(m) } // ReturnIntSet 归还整数集合 func ReturnIntSet(m map[int]struct{}) { IntToStructMapPool.Put(m) } // SetPool 专门用于集合操作的池 type SetPool[T comparable] struct { pool sync.Pool reused int64 maxSize int } // NewSetPool 创建新的集合池 func NewSetPool[T comparable](maxSize int) *SetPool[T] { if maxSize <= 0 { maxSize = 1024 } return &SetPool[T]{ pool: sync.Pool{ New: func() interface{} { m := make(map[T]struct{}, 16) return &m }, }, maxSize: maxSize, } } // Get 获取集合 func (p *SetPool[T]) Get() map[T]struct{} { mapPtr := p.pool.Get().(*map[T]struct{}) m := *mapPtr // 清空现有内容 for k := range m { delete(m, k) } atomic.AddInt64(&p.reused, 1) return m } // Put 归还集合 func (p *SetPool[T]) Put(m map[T]struct{}) { if m == nil { return } if len(m) > p.maxSize { return } p.pool.Put(&m) } // GetReusedCount 获取复用次数 func (p *SetPool[T]) GetReusedCount() int64 { return atomic.LoadInt64(&p.reused) } // 全局集合池 var ( StringSetPool = NewSetPool[string](1024) IntSetPool = NewSetPool[int](1024) )