github.com/squaremo/docker@v1.3.2-0.20150516120342-42cfc9554972/pkg/pools/pools.go (about) 1 // Package pools provides a collection of pools which provide various 2 // data types with buffers. These can be used to lower the number of 3 // memory allocations and reuse buffers. 4 // 5 // New pools should be added to this package to allow them to be 6 // shared across packages. 7 // 8 // Utility functions which operate on pools should be added to this 9 // package to allow them to be reused. 10 package pools 11 12 import ( 13 "bufio" 14 "io" 15 "sync" 16 17 "github.com/docker/docker/pkg/ioutils" 18 ) 19 20 var ( 21 // Pool which returns bufio.Reader with a 32K buffer 22 BufioReader32KPool *BufioReaderPool 23 // Pool which returns bufio.Writer with a 32K buffer 24 BufioWriter32KPool *BufioWriterPool 25 ) 26 27 const buffer32K = 32 * 1024 28 29 type BufioReaderPool struct { 30 pool sync.Pool 31 } 32 33 func init() { 34 BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K) 35 BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K) 36 } 37 38 // newBufioReaderPoolWithSize is unexported because new pools should be 39 // added here to be shared where required. 40 func newBufioReaderPoolWithSize(size int) *BufioReaderPool { 41 pool := sync.Pool{ 42 New: func() interface{} { return bufio.NewReaderSize(nil, size) }, 43 } 44 return &BufioReaderPool{pool: pool} 45 } 46 47 // Get returns a bufio.Reader which reads from r. The buffer size is that of the pool. 48 func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader { 49 buf := bufPool.pool.Get().(*bufio.Reader) 50 buf.Reset(r) 51 return buf 52 } 53 54 // Put puts the bufio.Reader back into the pool. 55 func (bufPool *BufioReaderPool) Put(b *bufio.Reader) { 56 b.Reset(nil) 57 bufPool.pool.Put(b) 58 } 59 60 // NewReadCloserWrapper returns a wrapper which puts the bufio.Reader back 61 // into the pool and closes the reader if it's an io.ReadCloser. 62 func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser { 63 return ioutils.NewReadCloserWrapper(r, func() error { 64 if readCloser, ok := r.(io.ReadCloser); ok { 65 readCloser.Close() 66 } 67 bufPool.Put(buf) 68 return nil 69 }) 70 } 71 72 type BufioWriterPool struct { 73 pool sync.Pool 74 } 75 76 // newBufioWriterPoolWithSize is unexported because new pools should be 77 // added here to be shared where required. 78 func newBufioWriterPoolWithSize(size int) *BufioWriterPool { 79 pool := sync.Pool{ 80 New: func() interface{} { return bufio.NewWriterSize(nil, size) }, 81 } 82 return &BufioWriterPool{pool: pool} 83 } 84 85 // Get returns a bufio.Writer which writes to w. The buffer size is that of the pool. 86 func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer { 87 buf := bufPool.pool.Get().(*bufio.Writer) 88 buf.Reset(w) 89 return buf 90 } 91 92 // Put puts the bufio.Writer back into the pool. 93 func (bufPool *BufioWriterPool) Put(b *bufio.Writer) { 94 b.Reset(nil) 95 bufPool.pool.Put(b) 96 } 97 98 // NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back 99 // into the pool and closes the writer if it's an io.Writecloser. 100 func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser { 101 return ioutils.NewWriteCloserWrapper(w, func() error { 102 buf.Flush() 103 if writeCloser, ok := w.(io.WriteCloser); ok { 104 writeCloser.Close() 105 } 106 bufPool.Put(buf) 107 return nil 108 }) 109 }