compressor_pools.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package restful
  2. // Copyright 2015 Ernest Micklei. All rights reserved.
  3. // Use of this source code is governed by a license
  4. // that can be found in the LICENSE file.
  5. import (
  6. "bytes"
  7. "compress/gzip"
  8. "compress/zlib"
  9. "sync"
  10. )
  11. // SyncPoolCompessors is a CompressorProvider that use the standard sync.Pool.
  12. type SyncPoolCompessors struct {
  13. GzipWriterPool *sync.Pool
  14. GzipReaderPool *sync.Pool
  15. ZlibWriterPool *sync.Pool
  16. }
  17. // NewSyncPoolCompessors returns a new ("empty") SyncPoolCompessors.
  18. func NewSyncPoolCompessors() *SyncPoolCompessors {
  19. return &SyncPoolCompessors{
  20. GzipWriterPool: &sync.Pool{
  21. New: func() interface{} { return newGzipWriter() },
  22. },
  23. GzipReaderPool: &sync.Pool{
  24. New: func() interface{} { return newGzipReader() },
  25. },
  26. ZlibWriterPool: &sync.Pool{
  27. New: func() interface{} { return newZlibWriter() },
  28. },
  29. }
  30. }
  31. func (s *SyncPoolCompessors) AcquireGzipWriter() *gzip.Writer {
  32. return s.GzipWriterPool.Get().(*gzip.Writer)
  33. }
  34. func (s *SyncPoolCompessors) ReleaseGzipWriter(w *gzip.Writer) {
  35. s.GzipWriterPool.Put(w)
  36. }
  37. func (s *SyncPoolCompessors) AcquireGzipReader() *gzip.Reader {
  38. return s.GzipReaderPool.Get().(*gzip.Reader)
  39. }
  40. func (s *SyncPoolCompessors) ReleaseGzipReader(r *gzip.Reader) {
  41. s.GzipReaderPool.Put(r)
  42. }
  43. func (s *SyncPoolCompessors) AcquireZlibWriter() *zlib.Writer {
  44. return s.ZlibWriterPool.Get().(*zlib.Writer)
  45. }
  46. func (s *SyncPoolCompessors) ReleaseZlibWriter(w *zlib.Writer) {
  47. s.ZlibWriterPool.Put(w)
  48. }
  49. func newGzipWriter() *gzip.Writer {
  50. // create with an empty bytes writer; it will be replaced before using the gzipWriter
  51. writer, err := gzip.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed)
  52. if err != nil {
  53. panic(err.Error())
  54. }
  55. return writer
  56. }
  57. func newGzipReader() *gzip.Reader {
  58. // create with an empty reader (but with GZIP header); it will be replaced before using the gzipReader
  59. // we can safely use currentCompressProvider because it is set on package initialization.
  60. w := currentCompressorProvider.AcquireGzipWriter()
  61. defer currentCompressorProvider.ReleaseGzipWriter(w)
  62. b := new(bytes.Buffer)
  63. w.Reset(b)
  64. w.Flush()
  65. w.Close()
  66. reader, err := gzip.NewReader(bytes.NewReader(b.Bytes()))
  67. if err != nil {
  68. panic(err.Error())
  69. }
  70. return reader
  71. }
  72. func newZlibWriter() *zlib.Writer {
  73. writer, err := zlib.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed)
  74. if err != nil {
  75. panic(err.Error())
  76. }
  77. return writer
  78. }