-
Notifications
You must be signed in to change notification settings - Fork 33
/
buffer_pool.go
63 lines (56 loc) · 1.41 KB
/
buffer_pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package falcore
import (
"bufio"
"io"
"io/ioutil"
)
// uses a chan as a leaky bucket buffer pool
type bufferPool struct {
// size of buffer when creating new ones
bufSize int
// the actual pool of buffers ready for reuse
pool chan *bufferPoolEntry
}
// This is what's stored in the buffer. It allows
// for the underlying io.Reader to be changed out
// inside a bufio.Reader. This is required for reuse.
type bufferPoolEntry struct {
br *bufio.Reader
source io.Reader
}
// make bufferPoolEntry a passthrough io.Reader
func (bpe *bufferPoolEntry) Read(p []byte) (n int, err error) {
return bpe.source.Read(p)
}
func newBufferPool(poolSize, bufferSize int) *bufferPool {
return &bufferPool{
bufSize: bufferSize,
pool: make(chan *bufferPoolEntry, poolSize),
}
}
// Take a buffer from the pool and set
// it up to read from r
func (p *bufferPool) take(r io.Reader) (bpe *bufferPoolEntry) {
select {
case bpe = <-p.pool:
// prepare for reuse
if a := bpe.br.Buffered(); a > 0 {
// drain the internal buffer
io.CopyN(ioutil.Discard, bpe.br, int64(a))
}
// swap out the underlying reader
bpe.source = r
default:
// none available. create a new one
bpe = &bufferPoolEntry{nil, r}
bpe.br = bufio.NewReaderSize(bpe, p.bufSize)
}
return
}
// Return a buffer to the pool
func (p *bufferPool) give(bpe *bufferPoolEntry) {
select {
case p.pool <- bpe: // return to pool
default: // discard
}
}