mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 05:56:46 +08:00

- 重命名 Common -> common,WebScan -> webscan,遵循 Go 包命名约定 - 修复模块路径大小写不匹配导致的编译错误 - 清理依赖项,优化 go.mod 文件 - 添加 Docker 测试环境配置文件 - 新增镜像拉取脚本以处理网络超时问题 - 成功编译生成 fscan v2.2.1 可执行文件 该修复解决了 Linux 系统下包名大小写敏感导致的模块解析失败问题。
129 lines
2.7 KiB
Go
129 lines
2.7 KiB
Go
package utils
|
||
|
||
import (
|
||
"strconv"
|
||
"strings"
|
||
"sync"
|
||
"sync/atomic"
|
||
)
|
||
|
||
// StringBuilderPool 字符串构建器池
|
||
type StringBuilderPool struct {
|
||
pool sync.Pool
|
||
reused int64 // 复用计数器
|
||
maxSize int // 最大保留大小,防止内存无限增长
|
||
}
|
||
|
||
// NewStringBuilderPool 创建新的字符串构建器池
|
||
func NewStringBuilderPool(maxSize int) *StringBuilderPool {
|
||
if maxSize <= 0 {
|
||
maxSize = 64 * 1024 // 默认64KB最大保留大小
|
||
}
|
||
|
||
return &StringBuilderPool{
|
||
pool: sync.Pool{
|
||
New: func() interface{} {
|
||
return &strings.Builder{}
|
||
},
|
||
},
|
||
maxSize: maxSize,
|
||
}
|
||
}
|
||
|
||
// Get 获取字符串构建器
|
||
func (p *StringBuilderPool) Get() *strings.Builder {
|
||
builder := p.pool.Get().(*strings.Builder)
|
||
builder.Reset() // 清空内容但保留容量
|
||
atomic.AddInt64(&p.reused, 1)
|
||
return builder
|
||
}
|
||
|
||
// Put 归还字符串构建器
|
||
func (p *StringBuilderPool) Put(builder *strings.Builder) {
|
||
if builder == nil {
|
||
return
|
||
}
|
||
|
||
// 如果容量超过最大限制,不放回池中以避免内存泄露
|
||
if builder.Cap() > p.maxSize {
|
||
return
|
||
}
|
||
|
||
p.pool.Put(builder)
|
||
}
|
||
|
||
// JoinStrings 高效连接字符串切片
|
||
func (p *StringBuilderPool) JoinStrings(slice []string, sep string) string {
|
||
if len(slice) == 0 {
|
||
return ""
|
||
}
|
||
if len(slice) == 1 {
|
||
return slice[0]
|
||
}
|
||
|
||
builder := p.Get()
|
||
defer p.Put(builder)
|
||
|
||
// 预估容量:所有字符串长度 + 分隔符长度
|
||
var totalLen int
|
||
for _, s := range slice {
|
||
totalLen += len(s)
|
||
}
|
||
totalLen += len(sep) * (len(slice) - 1)
|
||
|
||
// 如果当前容量不足,预先增长
|
||
if builder.Cap() < totalLen {
|
||
builder.Grow(totalLen)
|
||
}
|
||
|
||
builder.WriteString(slice[0])
|
||
for i := 1; i < len(slice); i++ {
|
||
builder.WriteString(sep)
|
||
builder.WriteString(slice[i])
|
||
}
|
||
|
||
return builder.String()
|
||
}
|
||
|
||
// JoinInts 高效连接整数切片
|
||
func (p *StringBuilderPool) JoinInts(slice []int, sep string) string {
|
||
if len(slice) == 0 {
|
||
return ""
|
||
}
|
||
if len(slice) == 1 {
|
||
return strconv.Itoa(slice[0])
|
||
}
|
||
|
||
builder := p.Get()
|
||
defer p.Put(builder)
|
||
|
||
// 预估容量:平均每个整数4字符 + 分隔符
|
||
estimatedLen := len(slice)*4 + len(sep)*(len(slice)-1)
|
||
if builder.Cap() < estimatedLen {
|
||
builder.Grow(estimatedLen)
|
||
}
|
||
|
||
builder.WriteString(strconv.Itoa(slice[0]))
|
||
for i := 1; i < len(slice); i++ {
|
||
builder.WriteString(sep)
|
||
builder.WriteString(strconv.Itoa(slice[i]))
|
||
}
|
||
|
||
return builder.String()
|
||
}
|
||
|
||
|
||
|
||
// 全局字符串构建器池实例
|
||
var GlobalStringBuilderPool = NewStringBuilderPool(64 * 1024)
|
||
|
||
// 便捷函数,使用全局池
|
||
func JoinStrings(slice []string, sep string) string {
|
||
return GlobalStringBuilderPool.JoinStrings(slice, sep)
|
||
}
|
||
|
||
func JoinInts(slice []int, sep string) string {
|
||
return GlobalStringBuilderPool.JoinInts(slice, sep)
|
||
}
|
||
|