gotosocial/vendor/github.com/ulule/limiter/v3/internal/bytebuffer/pool.go

59 lines
1.4 KiB
Go
Raw Normal View History

package bytebuffer
import (
"sync"
"unsafe"
)
// ByteBuffer is a wrapper around a slice to reduce memory allocation while handling blob of data.
type ByteBuffer struct {
blob []byte
}
// New creates a new ByteBuffer instance.
func New() *ByteBuffer {
entry := bufferPool.Get().(*ByteBuffer)
entry.blob = entry.blob[:0]
return entry
}
// Bytes returns the content buffer.
func (buffer *ByteBuffer) Bytes() []byte {
return buffer.blob
}
// String returns the content buffer.
func (buffer *ByteBuffer) String() string {
// Copied from strings.(*Builder).String
return *(*string)(unsafe.Pointer(&buffer.blob)) // nolint: gosec
}
// Concat appends given arguments to blob content
func (buffer *ByteBuffer) Concat(args ...string) {
for i := range args {
buffer.blob = append(buffer.blob, args[i]...)
}
}
// Close recycles underlying resources of encoder.
func (buffer *ByteBuffer) Close() {
// Proper usage of a sync.Pool requires each entry to have approximately
// the same memory cost. To obtain this property when the stored type
// contains a variably-sized buffer, we add a hard limit on the maximum buffer
// to place back in the pool.
//
// See https://golang.org/issue/23199
if buffer != nil && cap(buffer.blob) < (1<<16) {
bufferPool.Put(buffer)
}
}
// A byte buffer pool to reduce memory allocation pressure.
var bufferPool = &sync.Pool{
New: func() interface{} {
return &ByteBuffer{
blob: make([]byte, 0, 1024),
}
},
}