buffer_pool.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package buf
  2. import (
  3. "sync"
  4. )
  5. const (
  6. // Size of a regular buffer.
  7. Size = 2 * 1024
  8. )
  9. func createAllocFunc(size int32) func() interface{} {
  10. return func() interface{} {
  11. return make([]byte, size)
  12. }
  13. }
  14. // The following parameters controls the size of buffer pools.
  15. // There are numPools pools. Starting from 2k size, the size of each pool is sizeMulti of the previous one.
  16. // Package buf is guaranteed to not use buffers larger than the largest pool.
  17. // Other packets may use larger buffers.
  18. const (
  19. numPools = 5
  20. sizeMulti = 4
  21. )
  22. var (
  23. pool [numPools]sync.Pool
  24. poolSize [numPools]int32
  25. largeSize int32
  26. )
  27. func init() {
  28. size := int32(Size)
  29. for i := 0; i < numPools; i++ {
  30. pool[i] = sync.Pool{
  31. New: createAllocFunc(size),
  32. }
  33. poolSize[i] = size
  34. largeSize = size
  35. size *= sizeMulti
  36. }
  37. }
  38. func newBytes(size int32) []byte {
  39. for idx, ps := range poolSize {
  40. if size <= ps {
  41. return pool[idx].Get().([]byte)
  42. }
  43. }
  44. return make([]byte, size)
  45. }
  46. func freeBytes(b []byte) {
  47. size := int32(cap(b))
  48. b = b[0:cap(b)]
  49. for i := numPools - 1; i >= 0; i-- {
  50. if size >= poolSize[i] {
  51. pool[i].Put(b)
  52. return
  53. }
  54. }
  55. }