github.com/Mericusta/go-stp@v0.6.8/pool.go (about) 1 package stp 2 3 import "unsafe" 4 5 // 内存反转函数 6 func tConvertByteArrayToObject[T any](b []byte) T { 7 return *(*T)(unsafe.Pointer(&b)) 8 } 9 10 type Pool[T any] struct { 11 eCount int 12 eSize int 13 last int 14 b []byte 15 } 16 17 func NewPool[T any](c int) *Pool[T] { 18 p := &Pool[T]{} 19 p.allocateMemory(c) 20 return p 21 } 22 23 func (p *Pool[T]) allocateMemory(c int) { 24 var e T 25 p.eSize = int(unsafe.Sizeof(e)) 26 p.eCount = c 27 p.b = make([]byte, p.eCount*p.eSize) 28 } 29 30 func (p *Pool[T]) isFree(b, e int) bool { 31 for _, b := range p.b[b:e] { 32 if b != 0 { 33 return false 34 } 35 } 36 return true 37 } 38 39 func (p *Pool[T]) scan(b, e int) int { 40 for i := b; i < e; i++ { 41 if !p.isFree(i*p.eSize, (i+1)*p.eSize) { 42 goto NEXT 43 } 44 return i 45 NEXT: 46 } 47 return -1 48 } 49 50 func (p *Pool[T]) Get() *T { 51 i := p.scan(p.last, p.eCount) 52 if i == -1 { 53 i = p.scan(0, p.last) 54 if i == -1 { 55 return nil 56 } 57 } 58 59 p.last = (i + 1) % p.eCount 60 return tConvertByteArrayToObject[*T](p.b[i*p.eSize : (i+1)*p.eSize]) 61 }