buffer_pool.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  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. SmallBufferSize = 1600 - defaultOffset
  48. BufferSize = 8*1024 - defaultOffset
  49. LargeBufferSize = 64*1024 - defaultOffset
  50. )
  51. var smallPool = NewBufferPool(1600, 128)
  52. var mediumPool = NewBufferPool(8*1024, 128)
  53. var largePool = NewBufferPool(64*1024, 64)