compressor_cache.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. "compress/gzip"
  7. "compress/zlib"
  8. )
  9. // BoundedCachedCompressors is a CompressorProvider that uses a cache with a fixed amount
  10. // of writers and readers (resources).
  11. // If a new resource is acquired and all are in use, it will return a new unmanaged resource.
  12. type BoundedCachedCompressors struct {
  13. gzipWriters chan *gzip.Writer
  14. gzipReaders chan *gzip.Reader
  15. zlibWriters chan *zlib.Writer
  16. writersCapacity int
  17. readersCapacity int
  18. }
  19. // NewBoundedCachedCompressors returns a new, with filled cache, BoundedCachedCompressors.
  20. func NewBoundedCachedCompressors(writersCapacity, readersCapacity int) *BoundedCachedCompressors {
  21. b := &BoundedCachedCompressors{
  22. gzipWriters: make(chan *gzip.Writer, writersCapacity),
  23. gzipReaders: make(chan *gzip.Reader, readersCapacity),
  24. zlibWriters: make(chan *zlib.Writer, writersCapacity),
  25. writersCapacity: writersCapacity,
  26. readersCapacity: readersCapacity,
  27. }
  28. for ix := 0; ix < writersCapacity; ix++ {
  29. b.gzipWriters <- newGzipWriter()
  30. b.zlibWriters <- newZlibWriter()
  31. }
  32. for ix := 0; ix < readersCapacity; ix++ {
  33. b.gzipReaders <- newGzipReader()
  34. }
  35. return b
  36. }
  37. // AcquireGzipWriter returns an resettable *gzip.Writer. Needs to be released.
  38. func (b *BoundedCachedCompressors) AcquireGzipWriter() *gzip.Writer {
  39. var writer *gzip.Writer
  40. select {
  41. case writer, _ = <-b.gzipWriters:
  42. default:
  43. // return a new unmanaged one
  44. writer = newGzipWriter()
  45. }
  46. return writer
  47. }
  48. // ReleaseGzipWriter accepts a writer (does not have to be one that was cached)
  49. // only when the cache has room for it. It will ignore it otherwise.
  50. func (b *BoundedCachedCompressors) ReleaseGzipWriter(w *gzip.Writer) {
  51. // forget the unmanaged ones
  52. if len(b.gzipWriters) < b.writersCapacity {
  53. b.gzipWriters <- w
  54. }
  55. }
  56. // AcquireGzipReader returns a *gzip.Reader. Needs to be released.
  57. func (b *BoundedCachedCompressors) AcquireGzipReader() *gzip.Reader {
  58. var reader *gzip.Reader
  59. select {
  60. case reader, _ = <-b.gzipReaders:
  61. default:
  62. // return a new unmanaged one
  63. reader = newGzipReader()
  64. }
  65. return reader
  66. }
  67. // ReleaseGzipReader accepts a reader (does not have to be one that was cached)
  68. // only when the cache has room for it. It will ignore it otherwise.
  69. func (b *BoundedCachedCompressors) ReleaseGzipReader(r *gzip.Reader) {
  70. // forget the unmanaged ones
  71. if len(b.gzipReaders) < b.readersCapacity {
  72. b.gzipReaders <- r
  73. }
  74. }
  75. // AcquireZlibWriter returns an resettable *zlib.Writer. Needs to be released.
  76. func (b *BoundedCachedCompressors) AcquireZlibWriter() *zlib.Writer {
  77. var writer *zlib.Writer
  78. select {
  79. case writer, _ = <-b.zlibWriters:
  80. default:
  81. // return a new unmanaged one
  82. writer = newZlibWriter()
  83. }
  84. return writer
  85. }
  86. // ReleaseZlibWriter accepts a writer (does not have to be one that was cached)
  87. // only when the cache has room for it. It will ignore it otherwise.
  88. func (b *BoundedCachedCompressors) ReleaseZlibWriter(w *zlib.Writer) {
  89. // forget the unmanaged ones
  90. if len(b.zlibWriters) < b.writersCapacity {
  91. b.zlibWriters <- w
  92. }
  93. }