forked from lunixbochs/struc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpool.go
208 lines (186 loc) · 5.9 KB
/
pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package struc
import (
"bytes"
"encoding/binary"
"reflect"
"sync"
"sync/atomic"
)
// MaxBufferCapSize 定义了缓冲区的最大容量限制
// 超过此限制的缓冲区不会被放入对象池
//
// MaxBufferCapSize defines the maximum capacity limit for buffers
// Buffers exceeding this limit will not be put into the object pool
const MaxBufferCapSize = 1 << 20
// MaxBytesSliceSize 定义了字节切片的最大容量限制
// 超过此限制的字节切片不会被放入对象池
//
// MaxBytesSliceSize defines the maximum capacity limit for byte slices
// Byte slices exceeding this limit will not be put into the object pool
const MaxBytesSliceSize = 4096
// bufferPool 用于减少[]byte的内存分配
// bufferPool is used to reduce allocations when []byte is used
var bufferPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(make([]byte, 0, 1024))
},
}
// fieldPool 是 Field 对象的全局池
// fieldPool is a global pool for Field objects
var fieldPool = sync.Pool{
New: func() interface{} {
return &Field{
Length: 1,
ByteOrder: binary.BigEndian, // 默认使用大端字节序 / Default to big-endian
}
},
}
// sizeofMapPool 是用于复用 sizeofMap 的对象池
// sizeofMapPool is an object pool for reusing sizeofMap
var sizeofMapPool = sync.Pool{
New: func() interface{} {
return make(map[string][]int)
},
}
// acquireSizeofMap 从对象池获取一个 sizeofMap
// acquireSizeofMap gets a sizeofMap from the pool
func acquireSizeofMap() map[string][]int {
return sizeofMapPool.Get().(map[string][]int)
}
// releaseSizeofMap 将 sizeofMap 放回对象池
// releaseSizeofMap puts a sizeofMap back to the pool
func releaseSizeofMap(m map[string][]int) {
if m == nil {
return
}
// 清空 map
// Clear the map
for k := range m {
delete(m, k)
}
sizeofMapPool.Put(m)
}
// acquireBuffer 从对象池获取缓冲区
// acquireBuffer gets a buffer from the pool
func acquireBuffer() *bytes.Buffer {
return bufferPool.Get().(*bytes.Buffer)
}
// releaseBuffer 将缓冲区放回对象池
// releaseBuffer returns a buffer to the pool
func releaseBuffer(buf *bytes.Buffer) {
if buf == nil || buf.Cap() > MaxBufferCapSize {
return
}
buf.Reset()
bufferPool.Put(buf)
}
// acquireField 从对象池获取一个 Field 对象
// acquireField gets a Field object from the pool
func acquireField() *Field {
return fieldPool.Get().(*Field)
}
// releaseField 将 Field 对象放回对象池
// releaseField puts a Field object back to the pool
func releaseField(f *Field) {
if f == nil {
return
}
// 重置字段状态
// Reset field state
f.Name = ""
f.IsPointer = false
f.Index = 0
f.Type = 0
f.defType = 0
f.IsArray = false
f.IsSlice = false
f.Length = 1
f.ByteOrder = binary.BigEndian
f.Sizeof = nil
f.Sizefrom = nil
f.NestFields = nil
f.kind = reflect.Invalid
fieldPool.Put(f)
}
// releaseFields 将 Fields 切片中的所有 Field 对象放回对象池
// releaseFields puts all Field objects in a Fields slice back to the pool
func releaseFields(fields Fields) {
if fields == nil {
return
}
for _, f := range fields {
releaseField(f)
}
}
// BytesSlicePool 是一个用于管理共享字节切片的结构体
// 它提供了线程安全的切片分配和重用功能
//
// BytesSlicePool is a structure for managing shared byte slices
// It provides thread-safe slice allocation and reuse functionality
type BytesSlicePool struct {
bytes []byte // 底层字节数组 / underlying byte array
offset int32 // 当前偏移量 / current offset position
size int // 当前块大小 / current block size
mu sync.Mutex // 互斥锁用于保护并发访问 / mutex for protecting concurrent access
}
// NewBytesSlicePool 创建一个新的 BytesSlicePool 实例
// 初始化时,会分配一个 4096 字节的字节数组
//
// NewBytesSlicePool creates a new BytesSlicePool instance
// Initializes with a 4096-byte byte array
func NewBytesSlicePool(size int) *BytesSlicePool {
// 如果 size 小于等于 0 或者大于 MaxBytesSliceSize,则使用 MaxBytesSliceSize
// If size is less than or equal to 0 or greater than MaxBytesSliceSize, use MaxBytesSliceSize
if size > MaxBytesSliceSize || size <= 0 {
size = MaxBytesSliceSize
}
return &BytesSlicePool{
bytes: make([]byte, size),
offset: 0,
size: size,
mu: sync.Mutex{},
}
}
// GetSlice 返回指定大小的字节切片
// 如果当前块空间不足,会分配新的块并重置偏移量
//
// GetSlice returns a byte slice of specified size
// If current block has insufficient space, allocates new block and resets offset
func (b *BytesSlicePool) GetSlice(size int) []byte {
// 如果请求的大小超过了最大限制,直接分配新的切片
// If the requested size exceeds the maximum limit, allocate a new slice directly
if size > b.size {
return make([]byte, size)
}
// 使用原子操作获取当前偏移量
// Use atomic operation to get current offset
offset := atomic.LoadInt32(&b.offset)
// 检查剩余空间是否足够
// Check if remaining space is sufficient
if int(offset)+size > b.size {
// 使用 CAS 操作尝试重置偏移量
// Use CAS operation to try reset offset
if atomic.CompareAndSwapInt32(&b.offset, offset, 0) {
// 成功重置偏移量,分配新的内存块
// Successfully reset offset, allocate new memory block
b.bytes = make([]byte, b.size)
}
// 重新获取偏移量
// Re-acquire offset
offset = atomic.LoadInt32(&b.offset)
}
// 使用 CAS 操作更新偏移量
// Use CAS operation to update offset
for {
currentOffset := offset
nextOffset := currentOffset + int32(size)
if atomic.CompareAndSwapInt32(&b.offset, currentOffset, nextOffset) {
// 成功更新偏移量,返回切片
// Successfully updated offset, return slice
return b.bytes[currentOffset:nextOffset]
}
// CAS 失败,重新获取偏移量并重试
// CAS failed, re-acquire offset and retry
offset = atomic.LoadInt32(&b.offset)
}
}