4
4
"bytes"
5
5
"compress/gzip"
6
6
"fmt"
7
- "io"
8
7
"sync"
9
8
10
9
snappy "github.com/eapache/go-xerial-snappy"
19
18
}
20
19
21
20
gzipReaderPool sync.Pool
21
+
22
+ bufferPool = sync.Pool {
23
+ New : func () interface {} {
24
+ return new (bytes.Buffer )
25
+ },
26
+ }
27
+
28
+ bytesPool = sync.Pool {
29
+ New : func () interface {} {
30
+ res := make ([]byte , 0 , 4096 )
31
+ return & res
32
+ },
33
+ }
22
34
)
23
35
24
36
func decompress (cc CompressionCodec , data []byte ) ([]byte , error ) {
@@ -38,9 +50,17 @@ func decompress(cc CompressionCodec, data []byte) ([]byte, error) {
38
50
return nil , err
39
51
}
40
52
41
- defer gzipReaderPool .Put (reader )
53
+ buffer := bufferPool .Get ().(* bytes.Buffer )
54
+ _ , err = buffer .ReadFrom (reader )
55
+ // copy the buffer to a new slice with the correct length
56
+ // reuse gzipReader and buffer
57
+ gzipReaderPool .Put (reader )
58
+ res := make ([]byte , buffer .Len ())
59
+ copy (res , buffer .Bytes ())
60
+ buffer .Reset ()
61
+ bufferPool .Put (buffer )
42
62
43
- return io . ReadAll ( reader )
63
+ return res , err
44
64
case CompressionSnappy :
45
65
return snappy .Decode (data )
46
66
case CompressionLZ4 :
@@ -50,11 +70,28 @@ func decompress(cc CompressionCodec, data []byte) ([]byte, error) {
50
70
} else {
51
71
reader .Reset (bytes .NewReader (data ))
52
72
}
53
- defer lz4ReaderPool .Put (reader )
73
+ buffer := bufferPool .Get ().(* bytes.Buffer )
74
+ _ , err := buffer .ReadFrom (reader )
75
+ // copy the buffer to a new slice with the correct length
76
+ // reuse lz4Reader and buffer
77
+ lz4ReaderPool .Put (reader )
78
+ res := make ([]byte , buffer .Len ())
79
+ copy (res , buffer .Bytes ())
80
+ buffer .Reset ()
81
+ bufferPool .Put (buffer )
54
82
55
- return io . ReadAll ( reader )
83
+ return res , err
56
84
case CompressionZSTD :
57
- return zstdDecompress (ZstdDecoderParams {}, nil , data )
85
+ buffer := * bytesPool .Get ().(* []byte )
86
+ var err error
87
+ buffer , err = zstdDecompress (ZstdDecoderParams {}, buffer , data )
88
+ // copy the buffer to a new slice with the correct length and reuse buffer
89
+ res := make ([]byte , len (buffer ))
90
+ copy (res , buffer )
91
+ buffer = buffer [:0 ]
92
+ bytesPool .Put (& buffer )
93
+
94
+ return res , err
58
95
default :
59
96
return nil , PacketDecodingError {fmt .Sprintf ("invalid compression specified (%d)" , cc )}
60
97
}
0 commit comments