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