bufpool.go raw

   1  package bufpool
   2  
   3  import (
   4  	"sync"
   5  
   6  	"next.orly.dev/pkg/nostr/utils/units"
   7  )
   8  
   9  const (
  10  	// BufferSize is the size of each buffer in the pool (1kb)
  11  	BufferSize = units.Kb
  12  )
  13  
  14  type B []byte
  15  
  16  func (b B) ToBytes() []byte { return b }
  17  
  18  var Pool = sync.Pool{
  19  	New: func() interface{} {
  20  		// Create a new buffer when the pool is empty
  21  		b := make([]byte, 0, BufferSize)
  22  		// log.T.C(
  23  		// 	func() string {
  24  		// 		ptr := unsafe.SliceData(b)
  25  		// 		return fmt.Sprintf("creating buffer at: %p", ptr)
  26  		// 	},
  27  		// )
  28  		return B(b)
  29  	},
  30  }
  31  
  32  // Get returns a buffer from the pool or creates a new one if the pool is empty.
  33  //
  34  // Example usage:
  35  //
  36  //	buf := bufpool.Get()
  37  //	defer bufpool.Put(buf)
  38  //	// Use buf...
  39  func Get() B {
  40  	b := Pool.Get().(B)
  41  	// log.T.C(
  42  	// 	func() string {
  43  	// 		ptr := unsafe.SliceData(b)
  44  	// 		return fmt.Sprintf("getting buffer at: %p", ptr)
  45  	// 	},
  46  	// )
  47  	return b
  48  }
  49  
  50  // Put returns a buffer to the pool.
  51  // Buffers should be returned to the pool when no longer needed to allow reuse.
  52  func Put(b B) {
  53  	for i := range b {
  54  		(b)[i] = 0
  55  	}
  56  	b = b[:0]
  57  	// log.T.C(
  58  	// 	func() string {
  59  	// 		ptr := unsafe.SliceData(b)
  60  	// 		return fmt.Sprintf("returning to buffer: %p", ptr)
  61  	// 	},
  62  	// )
  63  	Pool.Put(b)
  64  }
  65  
  66  // PutBytes returns a buffer was not necessarily created by Get().
  67  func PutBytes(b []byte) {
  68  	// log.T.C(
  69  	// 	func() string {
  70  	// 		ptr := unsafe.SliceData(b)
  71  	// 		return fmt.Sprintf("returning bytes to buffer: %p", ptr)
  72  	// 	},
  73  	// )
  74  	b = b[:0]
  75  	Put(b)
  76  }
  77