diff options
Diffstat (limited to 'vendor/github.com/djherbis/buffer/pool.go')
-rw-r--r-- | vendor/github.com/djherbis/buffer/pool.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/vendor/github.com/djherbis/buffer/pool.go b/vendor/github.com/djherbis/buffer/pool.go new file mode 100644 index 0000000000..0e57de8406 --- /dev/null +++ b/vendor/github.com/djherbis/buffer/pool.go @@ -0,0 +1,111 @@ +package buffer + +import ( + "bytes" + "encoding/binary" + "encoding/gob" + "io/ioutil" + "os" + "sync" +) + +// Pool provides a way to Allocate and Release Buffer objects +// Pools mut be concurrent-safe for calls to Get() and Put(). +type Pool interface { + Get() (Buffer, error) // Allocate a Buffer + Put(buf Buffer) error // Release or Reuse a Buffer +} + +type pool struct { + pool sync.Pool +} + +// NewPool returns a Pool(), it's backed by a sync.Pool so its safe for concurrent use. +// Get() and Put() errors will always be nil. +// It will not work with gob. +func NewPool(New func() Buffer) Pool { + return &pool{ + pool: sync.Pool{ + New: func() interface{} { + return New() + }, + }, + } +} + +func (p *pool) Get() (Buffer, error) { + return p.pool.Get().(Buffer), nil +} + +func (p *pool) Put(buf Buffer) error { + buf.Reset() + p.pool.Put(buf) + return nil +} + +type memPool struct { + N int64 + Pool +} + +// NewMemPool returns a Pool, Get() returns an in memory buffer of max size N. +// Put() returns the buffer to the pool after resetting it. +// Get() and Put() errors will always be nil. +func NewMemPool(N int64) Pool { + return &memPool{ + N: N, + Pool: NewPool(func() Buffer { + return New(N) + }), + } +} + +func (m *memPool) MarshalBinary() ([]byte, error) { + buf := bytes.NewBuffer(nil) + err := binary.Write(buf, binary.LittleEndian, m.N) + return buf.Bytes(), err +} + +func (m *memPool) UnmarshalBinary(data []byte) error { + buf := bytes.NewReader(data) + err := binary.Read(buf, binary.LittleEndian, &m.N) + m.Pool = NewPool(func() Buffer { + return New(m.N) + }) + return err +} + +type filePool struct { + N int64 + Directory string +} + +// NewFilePool returns a Pool, Get() returns a file-based buffer of max size N. +// Put() closes and deletes the underlying file for the buffer. +// Get() may return an error if it fails to create a file for the buffer. +// Put() may return an error if it fails to delete the file. +func NewFilePool(N int64, dir string) Pool { + return &filePool{N: N, Directory: dir} +} + +func (p *filePool) Get() (Buffer, error) { + file, err := ioutil.TempFile(p.Directory, "buffer") + if err != nil { + return nil, err + } + return NewFile(p.N, file), nil +} + +func (p *filePool) Put(buf Buffer) (err error) { + buf.Reset() + if fileBuf, ok := buf.(*fileBuffer); ok { + fileBuf.file.Close() + err = os.Remove(fileBuf.file.Name()) + } + return err +} + +func init() { + gob.Register(&memPool{}) + gob.Register(&filePool{}) +} |