buffer_pool.go 1.1 KB

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