buffer.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. func (b *Buffer) Write(data []byte) (int, error) {
  43. b.Append(data)
  44. return len(data), nil
  45. }
  46. type bufferPool struct {
  47. chain chan []byte
  48. bufferSize int
  49. buffers2Keep int
  50. }
  51. func newBufferPool(bufferSize, buffers2Keep, poolSize int) *bufferPool {
  52. pool := &bufferPool{
  53. chain: make(chan []byte, poolSize),
  54. bufferSize: bufferSize,
  55. buffers2Keep: buffers2Keep,
  56. }
  57. for i := 0; i < buffers2Keep; i++ {
  58. pool.chain <- make([]byte, bufferSize)
  59. }
  60. go pool.cleanup(time.Tick(1 * time.Second))
  61. return pool
  62. }
  63. func (p *bufferPool) allocate() *Buffer {
  64. var b []byte
  65. select {
  66. case b = <-p.chain:
  67. default:
  68. b = make([]byte, p.bufferSize)
  69. }
  70. return &Buffer{
  71. head: b,
  72. pool: p,
  73. Value: b,
  74. }
  75. }
  76. func (p *bufferPool) free(buffer *Buffer) {
  77. select {
  78. case p.chain <- buffer.head:
  79. default:
  80. }
  81. }
  82. func (p *bufferPool) cleanup(tick <-chan time.Time) {
  83. for range tick {
  84. pSize := len(p.chain)
  85. if pSize > p.buffers2Keep {
  86. <-p.chain
  87. continue
  88. }
  89. for delta := p.buffers2Keep - pSize; delta > 0; delta-- {
  90. select {
  91. case p.chain <- make([]byte, p.bufferSize):
  92. default:
  93. }
  94. }
  95. }
  96. }
  97. var smallPool = newBufferPool(1024, 16, 64)
  98. var mediumPool = newBufferPool(8*1024, 256, 2048)
  99. var largePool = newBufferPool(64*1024, 16, 64)
  100. func NewSmallBuffer() *Buffer {
  101. return smallPool.allocate()
  102. }
  103. func NewBuffer() *Buffer {
  104. return mediumPool.allocate()
  105. }
  106. func NewLargeBuffer() *Buffer {
  107. return largePool.allocate()
  108. }