1 //go:build !(js && wasm)
2 3 // Package bufpool provides buffer pools for reducing GC pressure in hot paths.
4 //
5 // Two pool sizes are provided:
6 // - SmallPool (64 bytes): For index keys, serial encoding, short buffers
7 // - MediumPool (1KB): For event encoding, larger serialization buffers
8 //
9 // Usage:
10 //
11 // buf := bufpool.GetSmall()
12 // defer bufpool.PutSmall(buf)
13 // // Use buf...
14 // // IMPORTANT: Copy buf.Bytes() before Put if data is needed after
15 package bufpool
16 17 import (
18 "bytes"
19 "sync"
20 )
21 22 const (
23 // SmallBufferSize for index keys (8-64 bytes typical)
24 SmallBufferSize = 64
25 26 // MediumBufferSize for event encoding (300-1000 bytes typical)
27 MediumBufferSize = 1024
28 )
29 30 var (
31 // smallPool for index keys and short encodings
32 smallPool = sync.Pool{
33 New: func() interface{} {
34 return bytes.NewBuffer(make([]byte, 0, SmallBufferSize))
35 },
36 }
37 38 // mediumPool for event encoding and larger buffers
39 mediumPool = sync.Pool{
40 New: func() interface{} {
41 return bytes.NewBuffer(make([]byte, 0, MediumBufferSize))
42 },
43 }
44 )
45 46 // GetSmall returns a small buffer (64 bytes) from the pool.
47 // Call PutSmall when done to return it to the pool.
48 //
49 // WARNING: Copy buf.Bytes() before calling PutSmall if the data
50 // is needed after the buffer is returned to the pool.
51 func GetSmall() *bytes.Buffer {
52 return smallPool.Get().(*bytes.Buffer)
53 }
54 55 // PutSmall returns a small buffer to the pool.
56 // The buffer is reset before being returned.
57 func PutSmall(buf *bytes.Buffer) {
58 if buf == nil {
59 return
60 }
61 buf.Reset()
62 smallPool.Put(buf)
63 }
64 65 // GetMedium returns a medium buffer (1KB) from the pool.
66 // Call PutMedium when done to return it to the pool.
67 //
68 // WARNING: Copy buf.Bytes() before calling PutMedium if the data
69 // is needed after the buffer is returned to the pool.
70 func GetMedium() *bytes.Buffer {
71 return mediumPool.Get().(*bytes.Buffer)
72 }
73 74 // PutMedium returns a medium buffer to the pool.
75 // The buffer is reset before being returned.
76 func PutMedium(buf *bytes.Buffer) {
77 if buf == nil {
78 return
79 }
80 buf.Reset()
81 mediumPool.Put(buf)
82 }
83 84 // CopyBytes copies the buffer contents to a new slice.
85 // Use this before returning the buffer to the pool if the
86 // data needs to persist.
87 func CopyBytes(buf *bytes.Buffer) []byte {
88 if buf == nil || buf.Len() == 0 {
89 return nil
90 }
91 result := make([]byte, buf.Len())
92 copy(result, buf.Bytes())
93 return result
94 }
95