buffer.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package alloc
  2. import (
  3. "time"
  4. )
  5. type Buffer struct {
  6. head []byte
  7. pool *bufferPool
  8. Value []byte
  9. }
  10. func (b *Buffer) Release() {
  11. b.pool.free(b)
  12. b.head = nil
  13. b.Value = nil
  14. b.pool = nil
  15. }
  16. func (b *Buffer) Clear() *Buffer {
  17. b.Value = b.head[:0]
  18. return b
  19. }
  20. func (b *Buffer) AppendBytes(bytes ...byte) *Buffer {
  21. b.Value = append(b.Value, bytes...)
  22. return b
  23. }
  24. func (b *Buffer) Append(data []byte) *Buffer {
  25. b.Value = append(b.Value, data...)
  26. return b
  27. }
  28. func (b *Buffer) Slice(from, to int) *Buffer {
  29. b.Value = b.Value[from:to]
  30. return b
  31. }
  32. func (b *Buffer) SliceFrom(from int) *Buffer {
  33. b.Value = b.Value[from:]
  34. return b
  35. }
  36. func (b *Buffer) Len() int {
  37. return len(b.Value)
  38. }
  39. func (b *Buffer) IsFull() bool {
  40. return len(b.Value) == cap(b.Value)
  41. }
  42. type bufferPool struct {
  43. chain chan []byte
  44. bufferSize int
  45. buffers2Keep int
  46. }
  47. func newBufferPool(bufferSize, buffers2Keep, poolSize int) *bufferPool {
  48. pool := &bufferPool{
  49. chain: make(chan []byte, poolSize),
  50. bufferSize: bufferSize,
  51. buffers2Keep: buffers2Keep,
  52. }
  53. for i := 0; i < buffers2Keep; i++ {
  54. pool.chain <- make([]byte, bufferSize)
  55. }
  56. go pool.cleanup(time.Tick(1 * time.Second))
  57. return pool
  58. }
  59. func (p *bufferPool) allocate() *Buffer {
  60. var b []byte
  61. select {
  62. case b = <-p.chain:
  63. default:
  64. b = make([]byte, p.bufferSize)
  65. }
  66. return &Buffer{
  67. head: b,
  68. pool: p,
  69. Value: b,
  70. }
  71. }
  72. func (p *bufferPool) free(buffer *Buffer) {
  73. select {
  74. case p.chain <- buffer.head:
  75. default:
  76. }
  77. }
  78. func (p *bufferPool) cleanup(tick <-chan time.Time) {
  79. for range tick {
  80. pSize := len(p.chain)
  81. if pSize > p.buffers2Keep {
  82. <-p.chain
  83. continue
  84. }
  85. for delta := p.buffers2Keep - pSize; delta > 0; delta-- {
  86. p.chain <- make([]byte, p.bufferSize)
  87. }
  88. }
  89. }
  90. var smallPool = newBufferPool(1024, 16, 64)
  91. var mediumPool = newBufferPool(8*1024, 256, 2048)
  92. var largePool = newBufferPool(64*1024, 16, 64)
  93. func NewSmallBuffer() *Buffer {
  94. return smallPool.allocate()
  95. }
  96. func NewBuffer() *Buffer {
  97. return mediumPool.allocate()
  98. }
  99. func NewLargeBuffer() *Buffer {
  100. return largePool.allocate()
  101. }