pkg/pool: add pools for bufio readers & writers
Docker-DCO-1.1-Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com> (github: unclejack)
This commit is contained in:
		
							parent
							
								
									2a633df603
								
							
						
					
					
						commit
						884c3c7461
					
				
					 2 changed files with 184 additions and 0 deletions
				
			
		
							
								
								
									
										111
									
								
								pools/pools.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								pools/pools.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,111 @@ | |||
| // +build go1.3 | ||||
| 
 | ||||
| // Package pools provides a collection of pools which provide various | ||||
| // data types with buffers. These can be used to lower the number of | ||||
| // memory allocations and reuse buffers. | ||||
| // | ||||
| // New pools should be added to this package to allow them to be | ||||
| // shared across packages. | ||||
| // | ||||
| // Utility functions which operate on pools should be added to this | ||||
| // package to allow them to be reused. | ||||
| package pools | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"io" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/docker/docker/pkg/ioutils" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// Pool which returns bufio.Reader with a 32K buffer | ||||
| 	BufioReader32KPool *BufioReaderPool | ||||
| 	// Pool which returns bufio.Writer with a 32K buffer | ||||
| 	BufioWriter32KPool *BufioWriterPool | ||||
| ) | ||||
| 
 | ||||
| const buffer32K = 32 * 1024 | ||||
| 
 | ||||
| type BufioReaderPool struct { | ||||
| 	pool sync.Pool | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K) | ||||
| 	BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K) | ||||
| } | ||||
| 
 | ||||
| // newBufioReaderPoolWithSize is unexported because new pools should be | ||||
| // added here to be shared where required. | ||||
| func newBufioReaderPoolWithSize(size int) *BufioReaderPool { | ||||
| 	pool := sync.Pool{ | ||||
| 		New: func() interface{} { return bufio.NewReaderSize(nil, size) }, | ||||
| 	} | ||||
| 	return &BufioReaderPool{pool: pool} | ||||
| } | ||||
| 
 | ||||
| // Get returns a bufio.Reader which reads from r. The buffer size is that of the pool. | ||||
| func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader { | ||||
| 	buf := bufPool.pool.Get().(*bufio.Reader) | ||||
| 	buf.Reset(r) | ||||
| 	return buf | ||||
| } | ||||
| 
 | ||||
| // Put puts the bufio.Reader back into the pool. | ||||
| func (bufPool *BufioReaderPool) Put(b *bufio.Reader) { | ||||
| 	b.Reset(nil) | ||||
| 	bufPool.pool.Put(b) | ||||
| } | ||||
| 
 | ||||
| // NewReadCloserWrapper returns a wrapper which puts the bufio.Reader back | ||||
| // into the pool and closes the reader if it's an io.ReadCloser. | ||||
| func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser { | ||||
| 	return ioutils.NewReadCloserWrapper(r, func() error { | ||||
| 		if readCloser, ok := r.(io.ReadCloser); ok { | ||||
| 			readCloser.Close() | ||||
| 		} | ||||
| 		bufPool.Put(buf) | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type BufioWriterPool struct { | ||||
| 	pool sync.Pool | ||||
| } | ||||
| 
 | ||||
| // newBufioWriterPoolWithSize is unexported because new pools should be | ||||
| // added here to be shared where required. | ||||
| func newBufioWriterPoolWithSize(size int) *BufioWriterPool { | ||||
| 	pool := sync.Pool{ | ||||
| 		New: func() interface{} { return bufio.NewWriterSize(nil, size) }, | ||||
| 	} | ||||
| 	return &BufioWriterPool{pool: pool} | ||||
| } | ||||
| 
 | ||||
| // Get returns a bufio.Writer which writes to w. The buffer size is that of the pool. | ||||
| func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer { | ||||
| 	buf := bufPool.pool.Get().(*bufio.Writer) | ||||
| 	buf.Reset(w) | ||||
| 	return buf | ||||
| } | ||||
| 
 | ||||
| // Put puts the bufio.Writer back into the pool. | ||||
| func (bufPool *BufioWriterPool) Put(b *bufio.Writer) { | ||||
| 	b.Reset(nil) | ||||
| 	bufPool.pool.Put(b) | ||||
| } | ||||
| 
 | ||||
| // NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back | ||||
| // into the pool and closes the writer if it's an io.Writecloser. | ||||
| func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser { | ||||
| 	return ioutils.NewWriteCloserWrapper(w, func() error { | ||||
| 		buf.Flush() | ||||
| 		if writeCloser, ok := w.(io.WriteCloser); ok { | ||||
| 			writeCloser.Close() | ||||
| 		} | ||||
| 		bufPool.Put(buf) | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										73
									
								
								pools/pools_nopool.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								pools/pools_nopool.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| // +build !go1.3 | ||||
| 
 | ||||
| package pools | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/docker/docker/pkg/ioutils" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	BufioReader32KPool *BufioReaderPool | ||||
| 	BufioWriter32KPool *BufioWriterPool | ||||
| ) | ||||
| 
 | ||||
| const buffer32K = 32 * 1024 | ||||
| 
 | ||||
| type BufioReaderPool struct { | ||||
| 	size int | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K) | ||||
| 	BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K) | ||||
| } | ||||
| 
 | ||||
| func newBufioReaderPoolWithSize(size int) *BufioReaderPool { | ||||
| 	return &BufioReaderPool{size: size} | ||||
| } | ||||
| 
 | ||||
| func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader { | ||||
| 	return bufio.NewReaderSize(r, bufPool.size) | ||||
| } | ||||
| 
 | ||||
| func (bufPool *BufioReaderPool) Put(b *bufio.Reader) { | ||||
| 	b.Reset(nil) | ||||
| } | ||||
| 
 | ||||
| func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser { | ||||
| 	return ioutils.NewReadCloserWrapper(r, func() error { | ||||
| 		if readCloser, ok := r.(io.ReadCloser); ok { | ||||
| 			return readCloser.Close() | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type BufioWriterPool struct { | ||||
| 	size int | ||||
| } | ||||
| 
 | ||||
| func newBufioWriterPoolWithSize(size int) *BufioWriterPool { | ||||
| 	return &BufioWriterPool{size: size} | ||||
| } | ||||
| 
 | ||||
| func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer { | ||||
| 	return bufio.NewWriterSize(w, bufPool.size) | ||||
| } | ||||
| 
 | ||||
| func (bufPool *BufioWriterPool) Put(b *bufio.Writer) { | ||||
| 	b.Reset(nil) | ||||
| } | ||||
| 
 | ||||
| func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser { | ||||
| 	return ioutils.NewWriteCloserWrapper(w, func() error { | ||||
| 		buf.Flush() | ||||
| 		if writeCloser, ok := w.(io.WriteCloser); ok { | ||||
| 			return writeCloser.Close() | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue