buffer_pool.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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 &Buffer{
  29. head: b,
  30. pool: p,
  31. Value: b[defaultOffset:],
  32. offset: defaultOffset,
  33. }
  34. }
  35. func (p *BufferPool) Free(buffer *Buffer) {
  36. rawBuffer := buffer.head
  37. if rawBuffer == nil {
  38. return
  39. }
  40. select {
  41. case p.chain <- rawBuffer:
  42. default:
  43. p.allocator.Put(rawBuffer)
  44. }
  45. }
  46. const (
  47. BufferSize = 8*1024 - defaultOffset
  48. LargeBufferSize = 64*1024 - defaultOffset
  49. )
  50. var smallPool = NewBufferPool(1024, 64)
  51. var mediumPool = NewBufferPool(8*1024, 128)
  52. var largePool = NewBufferPool(64*1024, 64)