chore: cleanup allocator code
Some checks are pending
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, ubuntu-latest) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, ubuntu-latest) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, ubuntu-latest) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, ubuntu-latest) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Trigger CMFA Update / trigger-CMFA-update (push) Waiting to run

This commit is contained in:
wwqgtxx 2025-06-10 10:54:08 +08:00
parent 255ff5e977
commit 01f8f2db2f
5 changed files with 22 additions and 19 deletions

View File

@ -8,18 +8,23 @@ import (
"sync" "sync"
) )
var defaultAllocator = NewAllocator() var DefaultAllocator = NewAllocator()
// Allocator for incoming frames, optimized to prevent overwriting after zeroing type Allocator interface {
type Allocator struct { Get(size int) []byte
Put(buf []byte) error
}
// defaultAllocator for incoming frames, optimized to prevent overwriting after zeroing
type defaultAllocator struct {
buffers [11]sync.Pool buffers [11]sync.Pool
} }
// NewAllocator initiates a []byte allocator for frames less than 65536 bytes, // NewAllocator initiates a []byte allocator for frames less than 65536 bytes,
// the waste(memory fragmentation) of space allocation is guaranteed to be // the waste(memory fragmentation) of space allocation is guaranteed to be
// no more than 50%. // no more than 50%.
func NewAllocator() *Allocator { func NewAllocator() Allocator {
return &Allocator{ return &defaultAllocator{
buffers: [...]sync.Pool{ // 64B -> 64K buffers: [...]sync.Pool{ // 64B -> 64K
{New: func() any { return new([1 << 6]byte) }}, {New: func() any { return new([1 << 6]byte) }},
{New: func() any { return new([1 << 7]byte) }}, {New: func() any { return new([1 << 7]byte) }},
@ -37,7 +42,7 @@ func NewAllocator() *Allocator {
} }
// Get a []byte from pool with most appropriate cap // Get a []byte from pool with most appropriate cap
func (alloc *Allocator) Get(size int) []byte { func (alloc *defaultAllocator) Get(size int) []byte {
switch { switch {
case size < 0: case size < 0:
panic("alloc.Get: len out of range") panic("alloc.Get: len out of range")
@ -87,7 +92,7 @@ func (alloc *Allocator) Get(size int) []byte {
// Put returns a []byte to pool for future use, // Put returns a []byte to pool for future use,
// which the cap must be exactly 2^n // which the cap must be exactly 2^n
func (alloc *Allocator) Put(buf []byte) error { func (alloc *defaultAllocator) Put(buf []byte) error {
if cap(buf) == 0 || cap(buf) > 65536 { if cap(buf) == 0 || cap(buf) > 65536 {
return nil return nil
} }

View File

@ -3,13 +3,12 @@
package pool package pool
const ( const (
// RelayBufferSize using for tcp
// io.Copy default buffer size is 32 KiB // io.Copy default buffer size is 32 KiB
// but the maximum packet size of vmess/shadowsocks is about 16 KiB
// so define a buffer of 20 KiB to reduce the memory of each TCP relay
RelayBufferSize = 16 * 1024 RelayBufferSize = 16 * 1024
// RelayBufferSize uses 20KiB, but due to the allocator it will actually // UDPBufferSize using for udp
// request 32Kib. Most UDPs are smaller than the MTU, and the TUN's MTU // Most UDPs are smaller than the MTU, and the TUN's MTU
// set to 9000, so the UDP Buffer size set to 16Kib // set to 9000, so the UDP Buffer size set to 16Kib
UDPBufferSize = 8 * 1024 UDPBufferSize = 8 * 1024
) )

View File

@ -3,13 +3,12 @@
package pool package pool
const ( const (
// RelayBufferSize using for tcp
// io.Copy default buffer size is 32 KiB // io.Copy default buffer size is 32 KiB
// but the maximum packet size of vmess/shadowsocks is about 16 KiB RelayBufferSize = 32 * 1024
// so define a buffer of 20 KiB to reduce the memory of each TCP relay
RelayBufferSize = 20 * 1024
// RelayBufferSize uses 20KiB, but due to the allocator it will actually // UDPBufferSize using for udp
// request 32Kib. Most UDPs are smaller than the MTU, and the TUN's MTU // Most UDPs are smaller than the MTU, and the TUN's MTU
// set to 9000, so the UDP Buffer size set to 16Kib // set to 9000, so the UDP Buffer size set to 16Kib
UDPBufferSize = 16 * 1024 UDPBufferSize = 16 * 1024
) )

View File

@ -1,9 +1,9 @@
package pool package pool
func Get(size int) []byte { func Get(size int) []byte {
return defaultAllocator.Get(size) return DefaultAllocator.Get(size)
} }
func Put(buf []byte) error { func Put(buf []byte) error {
return defaultAllocator.Put(buf) return DefaultAllocator.Put(buf)
} }

View File

@ -3,5 +3,5 @@ package pool
import "github.com/metacubex/sing/common/buf" import "github.com/metacubex/sing/common/buf"
func init() { func init() {
buf.DefaultAllocator = defaultAllocator buf.DefaultAllocator = DefaultAllocator
} }