buffer_pool.go 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package alloc
  2. import (
  3. "sync"
  4. )
  5. type BufferPool struct {
  6. chain chan []byte
  7. allocator *sync.Pool
  8. }
  9. func NewBufferPool(bufferSize, poolSize int) *BufferPool {
  10. pool := &BufferPool{
  11. chain: make(chan []byte, poolSize),
  12. allocator: &sync.Pool{
  13. New: func() interface{} { return make([]byte, bufferSize) },
  14. },
  15. }
  16. for i := 0; i < poolSize/2; i++ {
  17. pool.chain <- make([]byte, bufferSize)
  18. }
  19. return pool
  20. }
  21. func (p *BufferPool) Allocate() *Buffer {
  22. var b []byte
  23. select {
  24. case b = <-p.chain:
  25. default:
  26. b = p.allocator.Get().([]byte)
  27. }
  28. return CreateBuffer(b, p)
  29. }
  30. func (p *BufferPool) Free(buffer *Buffer) {
  31. rawBuffer := buffer.head
  32. if rawBuffer == nil {
  33. return
  34. }
  35. select {
  36. case p.chain <- rawBuffer:
  37. default:
  38. p.allocator.Put(rawBuffer)
  39. }
  40. }
  41. const (
  42. SmallBufferSize = 1600 - defaultOffset
  43. BufferSize = 8*1024 - defaultOffset
  44. LargeBufferSize = 64*1024 - defaultOffset
  45. )
  46. var smallPool = NewBufferPool(1600, 128)
  47. var mediumPool = NewBufferPool(8*1024, 128)
  48. var largePool = NewBufferPool(64*1024, 64)