@@ -6,23 +6,52 @@ import (
6
6
"io"
7
7
"strings"
8
8
9
- "github.com/golang/snappy "
9
+ "github.com/klauspost/compress/s2 "
10
10
)
11
11
12
12
func init () {
13
13
RegisterFormat (Sz {})
14
14
}
15
15
16
- // Sz facilitates Snappy compression.
17
- type Sz struct {}
16
+ // Sz facilitates Snappy compression. It uses S2
17
+ // for reading and writing, but by default will
18
+ // write Snappy-compatible data.
19
+ type Sz struct {
20
+ // Configurable S2 extension.
21
+ S2 S2
22
+ }
23
+
24
+ // S2 is an extension of Snappy that can read Snappy
25
+ // streams and write Snappy-compatible streams, but
26
+ // can also be configured to write Snappy-incompatible
27
+ // streams for greater gains. See
28
+ // https://pkg.go.dev/github.com/klauspost/compress/s2
29
+ // for details and the documentation for each option.
30
+ type S2 struct {
31
+ // reader options
32
+ MaxBlockSize int
33
+ AllocBlock int
34
+ IgnoreStreamIdentifier bool
35
+ IgnoreCRC bool
36
+
37
+ // writer options
38
+ AddIndex bool
39
+ Compression S2Level
40
+ BlockSize int
41
+ Concurrency int
42
+ FlushOnWrite bool
43
+ Padding int
44
+ SnappyIncompatible bool
45
+ }
18
46
19
47
func (sz Sz ) Extension () string { return ".sz" }
20
48
21
49
func (sz Sz ) Match (_ context.Context , filename string , stream io.Reader ) (MatchResult , error ) {
22
50
var mr MatchResult
23
51
24
52
// match filename
25
- if strings .Contains (strings .ToLower (filename ), sz .Extension ()) {
53
+ if strings .Contains (strings .ToLower (filename ), sz .Extension ()) ||
54
+ strings .Contains (strings .ToLower (filename ), ".s2" ) {
26
55
mr .ByName = true
27
56
}
28
57
@@ -36,13 +65,68 @@ func (sz Sz) Match(_ context.Context, filename string, stream io.Reader) (MatchR
36
65
return mr , nil
37
66
}
38
67
39
- func (Sz ) OpenWriter (w io.Writer ) (io.WriteCloser , error ) {
40
- return snappy .NewBufferedWriter (w ), nil
68
+ func (sz Sz ) OpenWriter (w io.Writer ) (io.WriteCloser , error ) {
69
+ var opts []s2.WriterOption
70
+ if sz .S2 .AddIndex {
71
+ opts = append (opts , s2 .WriterAddIndex ())
72
+ }
73
+ switch sz .S2 .Compression {
74
+ case S2LevelNone :
75
+ opts = append (opts , s2 .WriterUncompressed ())
76
+ case S2LevelBetter :
77
+ opts = append (opts , s2 .WriterBetterCompression ())
78
+ case S2LevelBest :
79
+ opts = append (opts , s2 .WriterBestCompression ())
80
+ }
81
+ if sz .S2 .BlockSize != 0 {
82
+ opts = append (opts , s2 .WriterBlockSize (sz .S2 .BlockSize ))
83
+ }
84
+ if sz .S2 .Concurrency != 0 {
85
+ opts = append (opts , s2 .WriterConcurrency (sz .S2 .Concurrency ))
86
+ }
87
+ if sz .S2 .FlushOnWrite {
88
+ opts = append (opts , s2 .WriterFlushOnWrite ())
89
+ }
90
+ if sz .S2 .Padding != 0 {
91
+ opts = append (opts , s2 .WriterPadding (sz .S2 .Padding ))
92
+ }
93
+ if ! sz .S2 .SnappyIncompatible {
94
+ // this option is inverted because by default we should
95
+ // probably write Snappy-compatible streams
96
+ opts = append (opts , s2 .WriterSnappyCompat ())
97
+ }
98
+ return s2 .NewWriter (w , opts ... ), nil
41
99
}
42
100
43
- func (Sz ) OpenReader (r io.Reader ) (io.ReadCloser , error ) {
44
- return io .NopCloser (snappy .NewReader (r )), nil
101
+ func (sz Sz ) OpenReader (r io.Reader ) (io.ReadCloser , error ) {
102
+ var opts []s2.ReaderOption
103
+ if sz .S2 .AllocBlock != 0 {
104
+ opts = append (opts , s2 .ReaderAllocBlock (sz .S2 .AllocBlock ))
105
+ }
106
+ if sz .S2 .IgnoreCRC {
107
+ opts = append (opts , s2 .ReaderIgnoreCRC ())
108
+ }
109
+ if sz .S2 .IgnoreStreamIdentifier {
110
+ opts = append (opts , s2 .ReaderIgnoreStreamIdentifier ())
111
+ }
112
+ if sz .S2 .MaxBlockSize != 0 {
113
+ opts = append (opts , s2 .ReaderMaxBlockSize (sz .S2 .MaxBlockSize ))
114
+ }
115
+ return io .NopCloser (s2 .NewReader (r , opts ... )), nil
45
116
}
46
117
47
- // https://github.com/google/snappy/blob/master/framing_format.txt
118
+ // Compression level for S2 (Snappy/Sz extension).
119
+ // EXPERIMENTAL: May be changed or removed without a major version bump.
120
+ type S2Level int
121
+
122
+ // Compression levels for S2.
123
+ // EXPERIMENTAL: May be changed or removed without a major version bump.
124
+ const (
125
+ S2LevelNone S2Level = 0
126
+ S2LevelFast S2Level = 1
127
+ S2LevelBetter S2Level = 2
128
+ S2LevelBest S2Level = 3
129
+ )
130
+
131
+ // https://github.com/google/snappy/blob/master/framing_format.txt - contains "sNaPpY"
48
132
var snappyHeader = []byte {0xff , 0x06 , 0x00 , 0x00 , 0x73 , 0x4e , 0x61 , 0x50 , 0x70 , 0x59 }
0 commit comments