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  }