-
Notifications
You must be signed in to change notification settings - Fork 175
/
deflate.go
74 lines (62 loc) · 1.44 KB
/
deflate.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
64
65
66
67
68
69
70
71
72
73
74
// Package deflate implements and registers the DEFLATE compressor
// during initialization.
package deflate
import (
"compress/flate"
"io"
"sync"
"google.golang.org/grpc/encoding"
)
// Name is the name registered for the DEFLATE compressor.
const Name = "deflate"
func init() {
c := &compressor{}
w, _ := flate.NewWriter(nil, flate.DefaultCompression)
c.poolCompressor.New = func() interface{} {
return &writer{Writer: w, pool: &c.poolCompressor}
}
encoding.RegisterCompressor(c)
}
type compressor struct {
poolCompressor sync.Pool
poolDecompressor sync.Pool
}
func (c *compressor) Name() string {
return Name
}
func (c *compressor) Compress(w io.Writer) (io.WriteCloser, error) {
dw := c.poolCompressor.Get().(*writer)
dw.Reset(w)
return dw, nil
}
func (c *compressor) Decompress(r io.Reader) (io.Reader, error) {
dr, inPool := c.poolDecompressor.Get().(*reader)
if !inPool {
newR := flate.NewReader(r)
return &reader{ReadCloser: newR, pool: &c.poolDecompressor}, nil
}
if err := dr.ReadCloser.(flate.Resetter).Reset(r, nil); err != nil {
c.poolDecompressor.Put(dr)
return nil, err
}
return dr, nil
}
type writer struct {
*flate.Writer
pool *sync.Pool
}
func (w *writer) Close() error {
defer w.pool.Put(w)
return w.Writer.Close()
}
type reader struct {
io.ReadCloser
pool *sync.Pool
}
func (r *reader) Read(p []byte) (n int, err error) {
n, err = r.ReadCloser.Read(p)
if err == io.EOF {
r.pool.Put(r)
}
return n, err
}