github.com/ulule/limiter/v3@v3.11.3-0.20230613131926-4cb9c1da4633/internal/bytebuffer/pool.go (about) 1 package bytebuffer 2 3 import ( 4 "sync" 5 "unsafe" 6 ) 7 8 // ByteBuffer is a wrapper around a slice to reduce memory allocation while handling blob of data. 9 type ByteBuffer struct { 10 blob []byte 11 } 12 13 // New creates a new ByteBuffer instance. 14 func New() *ByteBuffer { 15 entry := bufferPool.Get().(*ByteBuffer) 16 entry.blob = entry.blob[:0] 17 return entry 18 } 19 20 // Bytes returns the content buffer. 21 func (buffer *ByteBuffer) Bytes() []byte { 22 return buffer.blob 23 } 24 25 // String returns the content buffer. 26 func (buffer *ByteBuffer) String() string { 27 // Copied from strings.(*Builder).String 28 return *(*string)(unsafe.Pointer(&buffer.blob)) // nolint: gosec 29 } 30 31 // Concat appends given arguments to blob content 32 func (buffer *ByteBuffer) Concat(args ...string) { 33 for i := range args { 34 buffer.blob = append(buffer.blob, args[i]...) 35 } 36 } 37 38 // Close recycles underlying resources of encoder. 39 func (buffer *ByteBuffer) Close() { 40 // Proper usage of a sync.Pool requires each entry to have approximately 41 // the same memory cost. To obtain this property when the stored type 42 // contains a variably-sized buffer, we add a hard limit on the maximum buffer 43 // to place back in the pool. 44 // 45 // See https://golang.org/issue/23199 46 if buffer != nil && cap(buffer.blob) < (1<<16) { 47 bufferPool.Put(buffer) 48 } 49 } 50 51 // A byte buffer pool to reduce memory allocation pressure. 52 var bufferPool = &sync.Pool{ 53 New: func() interface{} { 54 return &ByteBuffer{ 55 blob: make([]byte, 0, 1024), 56 } 57 }, 58 }