-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mutate: allow for custom compression
at least via the API for now :) Signed-off-by: Tycho Andersen <[email protected]>
- Loading branch information
Showing
7 changed files
with
130 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package mutate | ||
|
||
import ( | ||
"io" | ||
"io/ioutil" | ||
"runtime" | ||
|
||
gzip "github.com/klauspost/pgzip" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// Compressor is an interface which users can use to implement different | ||
// compression types. | ||
type Compressor interface { | ||
// Compress sets up the streaming compressor for this compression type. | ||
Compress(io.Reader) (io.ReadCloser, error) | ||
|
||
// MediaTypeSuffix returns the suffix to be added to the layer to | ||
// indicate what compression type is used, e.g. "gzip", or "" for no | ||
// compression. | ||
MediaTypeSuffix() string | ||
} | ||
|
||
type noopCompressor struct{} | ||
|
||
func (nc noopCompressor) Compress(r io.Reader) (io.ReadCloser, error) { | ||
return ioutil.NopCloser(r), nil | ||
} | ||
|
||
func (nc noopCompressor) MediaTypeSuffix() string { | ||
return "" | ||
} | ||
|
||
// NoopCompressor provides no compression. | ||
var NoopCompressor Compressor = noopCompressor{} | ||
|
||
// GzipCompressor provides gzip compression. | ||
var GzipCompressor Compressor = gzipCompressor{} | ||
|
||
type gzipCompressor struct{} | ||
|
||
func (gz gzipCompressor) Compress(reader io.Reader) (io.ReadCloser, error) { | ||
pipeReader, pipeWriter := io.Pipe() | ||
|
||
gzw := gzip.NewWriter(pipeWriter) | ||
if err := gzw.SetConcurrency(256<<10, 2*runtime.NumCPU()); err != nil { | ||
return nil, errors.Wrapf(err, "set concurrency level to %v blocks", 2*runtime.NumCPU()) | ||
} | ||
go func() { | ||
if _, err := io.Copy(gzw, reader); err != nil { | ||
// #nosec G104 | ||
_ = pipeWriter.CloseWithError(errors.Wrap(err, "compressing layer")) | ||
} | ||
if err := gzw.Close(); err != nil { | ||
// #nosec G104 | ||
_ = pipeWriter.CloseWithError(errors.Wrap(err, "close gzip writer")) | ||
} | ||
if err := pipeWriter.Close(); err != nil { | ||
// #nosec G104 | ||
_ = pipeWriter.CloseWithError(errors.Wrap(err, "close pipe writer")) | ||
} | ||
}() | ||
|
||
return pipeReader, nil | ||
} | ||
|
||
func (gz gzipCompressor) MediaTypeSuffix() string { | ||
return "gzip" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package mutate | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"testing" | ||
|
||
gzip "github.com/klauspost/pgzip" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const ( | ||
fact = "meshuggah rocks!!!" | ||
) | ||
|
||
func TestNoopCompressor(t *testing.T) { | ||
assert := assert.New(t) | ||
buf := bytes.NewBufferString(fact) | ||
|
||
r, err := NoopCompressor.Compress(buf) | ||
assert.NoError(err) | ||
assert.Equal(NoopCompressor.MediaTypeSuffix(), "") | ||
|
||
content, err := ioutil.ReadAll(r) | ||
assert.NoError(err) | ||
|
||
assert.Equal(string(content), fact) | ||
} | ||
|
||
func TestGzipCompressor(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
buf := bytes.NewBufferString(fact) | ||
c := GzipCompressor | ||
|
||
r, err := c.Compress(buf) | ||
assert.NoError(err) | ||
assert.Equal(c.MediaTypeSuffix(), "gzip") | ||
|
||
r, err = gzip.NewReader(r) | ||
assert.NoError(err) | ||
|
||
content, err := ioutil.ReadAll(r) | ||
assert.NoError(err) | ||
|
||
assert.Equal(string(content), fact) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters